基于图像掩膜和深度学习的花生豆分拣(附源码)

目录

项目介绍

图像分类网络构建

处理花生豆图片完成预测


项目介绍

这是一个使用图像掩膜技术和深度学习技术实现的一个花生豆分拣系统

我们有大量的花生豆图片,并以及打好了标签,可以看一下目录结构和几张具体的图片

 

同时我们也有几张大的图片,里面有若干花生豆,我们要做的任务就是将花生豆框住并且实现分类,可以看一下这些图片 

图像分类网络构建

这部分的内容和我上一篇博客几乎大同小异,就是把最后的分类个数和类别映射换了换,掌握了上一个项目,这部分相信也会理解的很快,这里附上网址并做简单的回顾

kaggle实战图像分类-Intel Image Classification(附源码)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_62428212/article/details/136059443?spm=1001.2014.3001.5501

1,数据集加载

2,构建网络

3,定义超参数训练网络

这里小编使用的是resnet18这个网络,因为花生豆数据集的训练,一不小心就会过拟合,用一些更深更强的网络很容易导致过拟合,resnet18好像也有点过拟合,这里附上训练结果图片

处理花生豆图片完成预测

我们训练好网络后,并不能直接将网络用于预测整个花生豆的大图,因为里面有很多的花生豆,所以我们可以取出并预测,那么怎么单独取出来呢,这里用到了掩膜用以分割花生豆(一些注释写在了代码里)

首先导入相应的库和定义一下参数

# -*- coding: GB2312 -*-
import os
import cv2
import numpy as np
import torch
from PIL import Image
from utils.model import ResNet18
from torchvision import transformspath = 'data/pic'
image_path = os.listdir(path)classify = {0: 'baiban', 1: 'bandian', 2: 'famei', 3: 'faya', 4: 'hongpi', 5: 'qipao', 6: 'youwu', 7: 'zhengchang'}transform = transforms.Compose([transforms.Resize((64, 64)),transforms.ToTensor()])net = ResNet18(8)
net.load_state_dict(torch.load('model_weights/ResNet18.pth'))min_size = 30
max_size = 400

然后我们加载整个大图的文件夹并遍历处理每张图片

for i in image_path:img = cv2.imread(os.path.join(path,i))hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # 转HSV色彩空间# 定义背景颜色区间(蓝色区间)lower_blue = np.array([100, 100, 8])upper_blue = np.array([255, 255, 255])mask = cv2.inRange(hsv, lower_blue, upper_blue)  # 创建掩膜(在上述颜色范围内(背景)为白色,不在(花生豆)则为黑色)result = cv2.bitwise_and(img, img, mask=mask)  # 根据掩膜提取图像,会将花生豆的部分变为黑色,然后提取出背景部分result = result.astype(np.uint8)_, binary_image = cv2.threshold(result, 1, 255, cv2.THRESH_BINARY)  # 三通道二值化。背景会全为白色,花生豆部分为黑色# 到这里我们就得到了经过掩膜过滤的图片,其中白色的为背景,黑色的为花生豆,我们可以看一下cv2.namedWindow('HSV_Result', cv2.WINDOW_NORMAL)cv2.resizeWindow('HSV_Result', 2840, 1000)cv2.imshow('HSV_Result', binary_image)cv2.waitKey(0)cv2.destroyAllWindows()

我们发现这些花生豆的背景是蓝色的,所以我们创建了一个用以区分背景和花生豆的掩膜用来分割二者,其分割完后的图片为

通过掩膜处理完后,我们可以清晰的观察到图片里的花生豆,后面我们就可以在这幅图片上画出轮廓并分割出花生豆部分依次放入网络预测

# 过滤边框
def delet_contours(contours, delete_list):delta = 0for i in range(len(delete_list)):del contours[delete_list[i] - delta]delta = delta + 1return contoursinverted_image = cv2.cvtColor(binary_image, cv2.COLOR_BGR2GRAY)  # 转灰度图_, binary_image = cv2.threshold(inverted_image, 1, 255, cv2.THRESH_BINARY)  # 单通道二值化contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)contours = list(contours)delete_list = []for i in range(len(contours)):# 通过框的周长去过滤边框if (cv2.arcLength(contours[i], True) < min_size) or (cv2.arcLength(contours[i], True) > max_size):delete_list.append(i)contours = delet_contours(contours, delete_list)# 遍历每一个框(取出每一个单独的花生豆进行预测)for i in range(len(contours)):x, y, w, h = cv2.boundingRect(contours[i])img_pred = img[y:y+h, x:x+w, :]img_pred = Image.fromarray(img_pred)  # 将numpy数组转为PIL图像对象img_pred = transform(img_pred)  # 调整图像尺寸和转tensor格式img_pred = torch.unsqueeze(img_pred, dim=0)  # 升一个维度pred = torch.argmax(net(img_pred), dim=1)  # 拿到概率最大的分类preds = classify[int(pred)]  # 数字映射为字符串cv2.putText(img, preds, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1, cv2.LINE_AA)  # 写类别标签cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)  # 画矩形框cv2.namedWindow('Result', cv2.WINDOW_NORMAL)cv2.resizeWindow('Result',2840,1000)cv2.imshow('Result', img)cv2.waitKey(0)cv2.destroyAllWindows()

展示一下预测结果

小编这里发现这个方法可以预测成功中间大多数的花生豆,但是边缘处的花生豆因不会被画出轮廓故不会被放入网络预测,大体预测的效果还算可以。

源码及数据集请查看:https://github.com/jvyou/Peanut-and-bean-sorting

视频讲解请查看:https://www.bilibili.com/video/BV13F4m1g7Wp/?spm_id_from=333.999.0.0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/676839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于片段的3D分子生成扩散模型 - AutoFragDiff 评测

AutoFragDiff 是一个基于片段的&#xff0c;自回归的&#xff0c;口袋条件下的&#xff0c;3D分子生成扩散模型。 AutoFragDiff方法来源于文章《Autoregressive fragment-based diffusion for pocket-aware ligand design》&#xff0c;由加州大学的Mahdi Ghorbani等人于2023年…

星辰AI大模型TeleChat-7B评测

0x0. 前言 受中电信 AI 科技有限公司的邀请&#xff0c;为他们近期开源的TeleChat-7B大模型做一个评测。 TeleChat-7B是由中电信 AI 科技有限公司发的第一个千亿级别大模型&#xff0c;基于transformer decoder架构和清洗后的1TB高质量数据训练而成&#xff0c;取得了相同参数…

【Java EE初阶十一】文件操作(IO)

1. 认识文件 所谓的文件是一个广义的概念&#xff0c;可以代表很多东西&#xff1b;在操作系统里面&#xff0c;会把很多的硬件设备和软件设备都抽象成“文件”&#xff0c;统一进行管理&#xff1b;但是大部分情况下&#xff0c;我们读到的文件&#xff0c;都是指硬盘的文件&a…

基础算法-高精度加法

基础算法-高精度加法 高精度算法 为什么要使用高精度算法 C 每一个变量都有自己的类型&#xff0c;每个类型都有自己的存储长度范围。 名称 关键字 字节 长度 短整型 short int 2 (-2的15次方)~(2的15次方-1) 整型 int 4 (-2的31次方)~(2的31次方…

MYSQL笔记:约束条件

MYSQL笔记&#xff1a;约束条件 主键约束 不能为空&#xff0c;值必须是不同的&#xff08;唯一性&#xff09; 一个表只能修饰一个主键 PRIMARY KEY自增约束 AUTO_INCREMENT唯一键约束 可以为空 unique非空约束 not null 默认值约束 default 外键约束 foreign key …

技术精英求职必备:大模型研发工程师简历制作指南

简历编写核心原则 当撰写针对专注于GPT系列大型语言模型的算法工程师职位的简历时&#xff0c;关键在于准确展现您在大型语言模型开发、自然语言处理和机器学习方面的专业技能、项目经验和技术成就。简历应作为您在GPT系列模型研发、数据处理、模型训练和优化能力的窗口&#…

CMD常用命令

目录 1.简介 2.基本功能 3.打开方式 4.常用命令 5.练习——通过CMD打开QQ 1.简介 CMD&#xff08;Command Prompt&#xff09;是Windows操作系统中的命令行界面工具&#xff0c;它允许用户通过键入文本命令来与操作系统进行交互。CMD提供了一种不依赖图形用户界面的方式来…

详解格式化输入函数scanf

大家好&#xff0c;今天给大家介绍详解格式化输入函数scanf&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 C语言中常用的输入可以有多种方式&#xff0c;如scanf(),getchar(),g…

centos中docker操作

一、安装docker 确保系统是CentOS 7并且内核版本高于3.10,可以通过uname -r命令查看内核版本。 更新系统软件包到最新版本,可以使用命令yum update -y。 安装必要的软件包,包括yum-utils、device-mapper-persistent-data和lvm2。使用命令yum install -y yum-utils devic…

【Mysql事务】

目录 前言 1.事务的特性是什么?可以详细说一下吗? 2.并发事务带来哪些问题&#xff1f;怎么解决这些问题呢&#xff1f;Mysql的默认隔离级别是&#xff1f; 3.undo log和redo log的区别。 4.事务中的隔离性是如何保证的&#xff08;解释一下MVCC&#xff09;? 5.主从同…

Mysql制作数据表

一.注意&#xff1a; 1.&#xff08;Mysql尽量用大写&#xff0c; 2.结尾为‘&#xff1b;’&#xff0c; 3.‘’与“”效果一样&#xff0c; 4.数据表名称显示时定为小写&#xff0c; 5.很多人教的时候喜欢用英文&#xff0c;我觉得麻烦&#xff0c;于是我用中文举例&…

moduleID的使用

整个平台上有很多相同的功能&#xff0c;但是需要不同的内容。例如各个模块自己的首页上有滚动新闻、有友好链接等等。为了公用这些功能&#xff0c;平台引入了moduleID的解决方案。 在前端的配置文件中&#xff0c;配置了模块号&#xff1a; 前端页面请求滚动新闻时&#xff0…

微软AD域替代方案,助力企业摆脱hw期间被攻击的窘境

在红蓝攻防演练&#xff08;hw行动&#xff09;中&#xff0c;AD域若被攻击成功&#xff0c;是其中一个扣分最多的一项内容。每年&#xff0c;宁盾都会接到大量AD在hw期间被攻击&#xff0c;甚至是被打穿的企业客户。过去&#xff0c;企业还会借助2FA双因子认证加强OA、Exchang…

LeetCode力扣 面试经典150题 详细题解 (1~5) 持续更新中

目录 1.合并两个有序数组 2.移动元素 3.删除有序数组中的重复项 4.删除排序数组中的重复项 II 暂时更新到这里&#xff0c;博主会持续更新的 1.合并两个有序数组 题目&#xff08;难度&#xff1a;简单&#xff09;&#xff1a; 给你两个按 非递减顺序 排列的整数数组 num…

ChatGPT高效提问—prompt常见用法(续篇七)

ChatGPT高效提问—prompt常见用法&#xff08;续篇七&#xff09; 1.1 零样本、单样本和多样本 ​ ChatGPT拥有令人惊叹的功能和能力&#xff0c;允许用户自由向其提问&#xff0c;无须提供任何具体的示例样本&#xff0c;就可以获得精准的回答。这种特性被称为零样本&#x…

Python编写远程控制工具--被控端的编写

本节将开始着手用Python编写远程控制工具。因篇幅限制&#xff0c;这里主要编写两 个常用的功能&#xff1a;命令执行和文件传输。当然&#xff0c;好的远程控制工具的功能远远不只 这些&#xff0c;读者可以在此基础上增加新的功能。具体步骤如下。 1&#xff09;编写主函数并…

每日一题——LeetCode1417.重新格式化字符串

方法一 个人方法&#xff1a; s里的字符只有小写字母和数字两种情况&#xff0c;我们可以把s里的字母和数字分隔成两个字符串&#xff0c; 比较两个字符串的长度&#xff0c;只有当两个字符串的长度差值的绝对值为1或0才能满足题意。 长度更长的要放在结果字符串的第一位&am…

写一个python基于线程池的多线程

下面是一个示例程序&#xff0c;它使用Python的concurrent.futures模块中的线程池来实现多线程操作&#xff1a; import concurrent.futuresdef worker(arg):print(fWorking on {arg})return arg * 2if __name__ __main__:# 创建线程池with concurrent.futures.ThreadPoolExe…

嵌入式学习之Linux入门篇笔记——18,makefile基本语法(下)

配套视频学习链接&#xff1a;http://【【北京迅为】嵌入式学习之Linux入门篇】 https://www.bilibili.com/video/BV1M7411m7wT/?p4&share_sourcecopy_web&vd_sourcea0ef2c4953d33a9260910aaea45eaec8 1.wildcard 函数 格式&#xff1a;$&#xff08;wildcard PAT…

SQL如何实现数据表行转列、列转行?

SQL行转列、列转行可以帮助我们更方便地处理数据&#xff0c;生成需要的报表和结果集。本文将介绍在SQL中如何实现数据表地行转列、列转行操作&#xff0c;以及实际应用示例。 这里通过表下面三张表进行举例 SQL创建数据库和数据表 数据表示例数据分别如下&#xff1a; data_…