基于OpenCV的谷物颗粒识别
基于OpenCV的谷物颗粒识别
- 一、程序整体功能介绍
- 1.1 导入库与函数定义
- 1.2 颜色分割与灰度处理
- 1.3 二值化与轮廓检测
- 1.4 绘制与计数
- 1.5 主程序与结果展示
- 二、算法原理与实现流程
- 2.1算法原理
- (1)颜色分割
- (2)灰度处理与二值化
- (3)轮廓检测与过滤
- (4)绘制轮廓与计数
- 2.2实现流程
- (1)图像加载与颜色分割
- (2)灰度处理与二值化
- (3)轮廓检测与过滤
- (4)绘制轮廓与计数
- (5)结果展示
- (6)主程序调用
- 三、程序运行界面及结果分析
- 3.1程序运行界面
- 3.2结果分析
- (1)程序参数调整
- (2)图像特性适配
- (3)计数结果准确性
- (4)用户友好性
- (5)结果的复现性
- (6)进一步优化的可能性
- 四、程序设计
一、程序整体功能介绍
1.1 导入库与函数定义
这个程序旨在通过图像处理技术实现对颗粒的计数。主要运用了计算机视觉库OpenCV以及数值计算库NumPy,通过颜色分割、灰度处理、二值化、轮廓检测等步骤,最终达到统计颗粒数量的目的。
首先,在程序的开头导入了必要的库,包括OpenCV用于图像处理,NumPy用于数组操作,以及Scikit-learn中的KMeans聚类算法,尽管在当前代码中并没有使用到KMeans算法,但可能为后续功能扩展保留了接口。
接下来定义一个名为grain_count的函数,该函数接受一个图像路径作为输入。在函数内部,首先使用OpenCV的imread函数读取了输入的图像。这一步是程序的起点,将图像加载到内存中以便后续处理。
1.2 颜色分割与灰度处理
接下来,程序进行了颜色分割的操作。通过将图像从BGR色彩空间转换为HSV色彩空间,程序能够更方便地选择特定颜色范围。通过设定HSV的上下阈值,程序创建了一个二值掩模,该掩模用于提取图像中特定颜色范围的像素。通过将这个掩模应用于原始图像,程序获得了一个仅包含感兴趣颜色的结果图像。程序对结果图像进行灰度处理,将其转换为单通道的灰度图像。这有助于简化图像,使得后续的处理步骤更为高效。
1.3 二值化与轮廓检测
程序进行二值化处理,将灰度图像转换为二值图像。通过设定一个阈值,像素的亮度高于阈值的被置为白色,低于阈值的被置为黑色。这一步骤是为了进一步简化图像,突出颗粒的轮廓。
然后,程序使用OpenCV的findContours函数来检测二值图像中的轮廓。这些轮廓代表了颗粒的形状,但在这一步中,并未对轮廓的大小进行过滤。接着,程序创建了一个全黑的图像,用于绘制筛选后的轮廓。
1.4 绘制与计数
在绘制轮廓的同时,程序通过计算轮廓的面积,对轮廓进行了过滤。只有当轮廓的面积大于50时,程序才将其计数,并在黑色图像上绘制相应的轮廓。这个阈值的选择是为了过滤掉一些噪声,确保只有较大的轮廓被计数,从而得到准确的颗粒数量。
最后,程序通过OpenCV展示了包含绘制轮廓的图像,等待用户按键后关闭窗口。函数返回被计数的颗粒数量。
1.5 主程序与结果展示
在主程序中,通过指定一个图像路径,调用了grain_count函数,并打印出了颗粒的数量。需要注意的是,代码中硬编码的期望颗粒数量(可能需要根据实际图像的特征进行调整。
总体而言,这个程序通过图像处理技术实现了对颗粒数量的计数,逐步进行颜色分割、灰度处理、二值化和轮廓检测等关键步骤,最终得到了准确的颗粒数量,并展示在了图像上。在实际应用中,用户只需替换图像路径,即可快速得到不同图像中颗粒的数量统计结果。
二、算法原理与实现流程
2.1算法原理
(1)颜色分割
颜色分割是图像处理中的一种常见技术,用于从图像中提取特定颜色范围的对象。在这个程序中,首先将图像从BGR色彩空间转换为HSV色彩空间。HSV表示图像的颜色信息更为直观,包括色相(Hue)、饱和度(Saturation)和亮度(Value)。通过设置在HSV空间中的颜色范围,程序创建了一个二值掩模,该掩模将位于指定颜色范围内的像素设为白色,而其他像素设为黑色。这一步骤的目的是提取出感兴趣颜色的部分,即颗粒的颜色。
(2)灰度处理与二值化
颜色分割后的图像通常仍然是一个多通道图像,为了简化后续处理,将其转换为灰度图像。灰度图像只有一个通道,表示图像的亮度信息。接着,通过设定一个阈值,将亮度高于阈值的像素置为白色,低于阈值的像素置为黑色,得到了二值图像。这一步的作用是突出颗粒的轮廓,方便后续的轮廓检测。
(3)轮廓检测与过滤
使用OpenCV的findContours函数来检测二值图像中的轮廓。每个轮廓是一系列相邻的像素点,代表了颗粒的形状。在这一步,程序检测到了所有的轮廓,而后通过计算轮廓的面积,过滤掉了面积较小的轮廓。过滤的目的是去除一些噪声或过小的区域,确保只有颗粒较大的轮廓被计数。
(4)绘制轮廓与计数
接下来,程序创建了一个全黑的图像,用于绘制筛选后的轮廓。通过遍历筛选后的轮廓,并通过drawContours函数在黑色图像上绘制,这一步将有助于可视化并进一步确认颗粒的位置。在绘制轮廓的同时,程序计数了有效的颗粒数量,即满足过滤条件的颗粒。
2.2实现流程
(1)图像加载与颜色分割
首先,使用OpenCV的imread函数加载输入的图像。随后,将图像从BGR色彩空间转换为HSV色彩空间,通过设定阈值范围,创建一个二值掩模,将图像中的感兴趣颜色提取出来。
(2)灰度处理与二值化
将颜色分割后的图像转换为灰度图像,简化后续处理。然后,通过设定阈值,将灰度图像转换为二值图像,突出颗粒的轮廓。
(3)轮廓检测与过滤
使用OpenCV的findContours函数检测二值图像中的轮廓。通过计算轮廓的面积,过滤掉面积较小的轮廓,以排除噪声。
(4)绘制轮廓与计数
创建一个全黑的图像,用于绘制筛选后的轮廓。遍历轮廓,绘制在黑色图像上,并计数有效的颗粒数量。
(5)结果展示
使用OpenCV展示包含绘制轮廓的图像,等待用户按键后关闭窗口。函数返回被计数的颗粒数量。
(6)主程序调用
在主程序中指定图像路径,调用grain_count函数,获取颗粒数量并打印。用户只需替换图像路径,即可快速得到不同图像中颗粒的数量统计结果。
整个实现流程通过图像处理的一系列步骤,从颜色分割到最终的轮廓计数,逐步提取并筛选出图像中的颗粒信息,最终得到准确的颗粒数量统计结果。
三、程序运行界面及结果分析
3.1程序运行界面


3.2结果分析
使用该颗粒计数程序对一张具有18颗谷物的图片进行计数并输出正确结果,表明程序在特定场景下取得了良好的效果。
(1)程序参数调整
通过使用该程序成功对一张图片中的18颗谷物进行计数,说明在这个特定场景下,程序的颜色分割、灰度处理、二值化等预处理步骤的参数设置较为合适。程序通过适当的参数选择,能够有效地区分出图像中的颗粒,而且过滤掉了可能的噪声。
(2)图像特性适配
成功的计数结果表明该程序对于一般的颗粒图像场景具有较好的适应性。程序通过检测轮廓并过滤,能够较好地应对不同颗粒大小和形状的情况,同时通过面积阈值的设定,有力地抑制了噪声对计数结果的干扰。
(3)计数结果准确性
输出的正确计数结果表明程序在对颗粒进行计数时具有较高的准确性。通过过滤掉面积较小的轮廓,程序成功排除了图像中的噪声,确保了计数结果的可靠性。程序的计数结果与实际图像中的颗粒数量一致,验证了其在此类任务上的有效性。
(4)用户友好性
程序通过在结果图像上绘制颗粒轮廓,以及直接输出颗粒数量,提供了用户友好的界面,使用户能够直观地了解计数结果。这种可视化的展示方式有助于用户对计数结果的直观理解,提高了程序的易用性。
(5)结果的复现性
由于程序对于特定场景的适应性较好,具有一定的鲁棒性和通用性,因此在不同的含有颗粒的图像上也可能取得类似的良好效果。用户在实际使用中,可以尝试将程序应用到其他颗粒图像中,观察其在不同场景下的表现。
(6)进一步优化的可能性
虽然程序在该场景下取得了正确的计数结果,但仍有可能通过进一步的参数调整和优化来提升程序的性能。例如,根据实际情况调整颜色范围、阈值等参数,或者考虑使用更复杂的图像处理算法,以适应更广泛的场景。
综合而言,程序在对一张具有18颗谷物的图片进行颗粒计数时取得了成功的结果,验证了其在特定场景下的有效性和准确性。这也为程序在其他颗粒图像中的应用提供了一定的信心。用户在使用程序时应关注实际图像的特性,可能需要进行一些参数的微调以适应不同的场景。
四、程序设计
import cv2
import numpy as np
from sklearn.cluster import KMeansdef grain_count(image_path):# 读取图像image = cv2.imread(image_path)# 颜色分割hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)lower_color = np.array([20, 50, 50])upper_color = np.array([30, 255, 255])mask = cv2.inRange(hsv, lower_color, upper_color)result = cv2.bitwise_and(image, image, mask=mask)# 灰度化gray = cv2.cvtColor(result, cv2.COLOR_BGR2GRAY)# 二值化_, thresh = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)# 查找轮廓_, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 创建一个黑色图像black_image = np.zeros_like(image)# 绘制轮廓并计数count = 0for contour in contours:area = cv2.contourArea(contour)if area > 50: # 过滤掉面积较小的轮廓,以排除噪声count += 1cv2.drawContours(black_image, [contour], -1, (0, 255, 0), 2)# 显示结果cv2.imshow("Contours", black_image)cv2.waitKey(0)cv2.destroyAllWindows()return countif __name__ == "__main__":image_path = "grains.jpeg" # 替换为实际图像路径count = grain_count(image_path)print(f"Number of grains: ",count)相关文章:
基于OpenCV的谷物颗粒识别
基于OpenCV的谷物颗粒识别 一、程序整体功能介绍1.1 导入库与函数定义1.2 颜色分割与灰度处理1.3 二值化与轮廓检测1.4 绘制与计数1.5 主程序与结果展示 二、算法原理与实现流程2.1算法原理(1)颜色分割(2)灰度处理与二值化&#x…...
Aloha 机械臂的学习记录3——AWE:Pycharm运行代码记录
之前的博客创作了三偏关于Aloha_AWE的liunx终端指令运行代码的示例: Aloha 机械臂的学习记录——AWE:Bimanual Simulation Suite: https://blog.csdn.net/qq_54900679/article/details/134889183?spm1001.2014.3001.5502 Aloha 机械臂的学习记录1——AWE&#x…...
开源协议概览
身为程序员,我们不可避免的要和开源项目打交道,不管是我们自己做了些开源项目,还是使用开源项目,对各种开源协议的了解是必要的。 OSI(Open Source Initiative) OSI,开发源代码组织,是一个旨在推动开源软件…...
分布式缓存
分布式缓存 缓存雪崩 缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库 CPU 和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应…...
BSC/平衡记分卡
一、Balanced Score Card BSC即平衡计分卡(Balanced Score Card),是常见的绩效考核方式之一,是从财务、客户、内部运营、学习与成长四个角度,将组织的战略落实为可操作的衡量指标和目标值的一种新型绩效管理体系。 是…...
论文阅读_训练大模型用于角色扮演
英文名称: Character-LLM: A Trainable Agent for Role-Playing 中文名称: 角色-LLM:训练Agent用于角色扮演 文章: [https://arxiv.org/abs/2310.10158](https://arxiv.org/abs/2310.10158) 作者: Yunfan Shao, Linyang Li, Junqi Dai, Xipeng Qiu 机构: 复旦大学…...
v-if控制div内容显示,克隆这个div但是v-if没有效果
问题描述: 我的子页面打印的时候通过isPdf来隐藏“选择参加人员”按钮。 我子页面有个el-dialog,el-dialog里面有个大的div它的id为app-pre-meet-add,在子页面我通过isPdf来显示我想要的内容。现在我在父页面先通过this.$refs.child.control…...
flutter的状态管理学习
文章目录 1.flutter widget分类2. 代理组件又分为3. 状态 state 数据4. 刷新 数据变化5. code 1.flutter widget分类 组合渲染代理 2. 代理组件又分为 Positioned向父组件传递数据InheritedWidget向子组件传递数据 3. 状态 state 数据 状态就是用到了向子组件传递数据ÿ…...
开源免费虚拟化KVM的部署及其虚拟机资源变更、快照、克隆等常见运维操作
实践说明:基于RHEL9(AlmaLinux9.1)部署,同类系统(CentOS9,RockyLinux9等)适用,但适用场景是不限于此的。 文档说明:本文档旨在帮助快速应用KVM虚拟化技术,重在实践操作,提供了简要参考。 文档形成时期&…...
阿里云git clone超时报错解决方法
参考:引用文章...
力扣刷题-二叉树-合并二叉树
617.合并二叉树(经典) 合并二叉树是操作两棵树的题目里面很经典的,如何对两棵树遍历以及处理? 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 你需要将他们合并…...
了解JavaScript 加密、混淆和生成签名
分析并理解网站的 JavaScript 加密、混淆和生成签名的方法是 JavaScript 逆向工程中的一个重要方面。这些技术通常用于保护代码免遭未授权的访问和修改,或确保数据在传输过程中的安全性。 加密 目的:加密用于保护敏感数据,使得只有拥有正确密…...
Go语言的指针(深度解析)
指针是Go语言中的一个重要概念,它提供了对内存地址的直接访问和操作能力。通过指针,我们可以高效地传递和修改变量的值,避免了值传递所带来的拷贝开销。在本文中,我们将深入探讨Go语言指针的概念、使用方法和注意事项。 指针的本…...
HTB-SAU
信息收集 # cat port.nmap # Nmap 7.94 scan initiated Thu Jan 11 19:26:51 2024 as: nmap -sS --min-rate 10000 -p- -oN port.nmap 10.10.11.224 Nmap scan report for 10.10.11.224 (10.10.11.224) Host is up (0.28s latency). Not shown: 65531 closed tcp ports (r…...
AI创新之美:AIGC探讨2024年春晚吉祥物龙辰辰的AI绘画之独特观点
🎬 鸽芷咕:个人主页 🔥 个人专栏:《粉丝福利》 《linux深造日志》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…...
Linux的SSH服务
一.SSH服务简介 1.什么是SSH SSH(Secure Shell)是一种安全通道协议,主要用来实现字符界面的远程登录、远程复制等功能。SSH 协议对通信双方的数据传输进行了加密处理,其中包括用户登录时输入的用户口令,SSH 为建立在应…...
MySQL连续案例续集
01)查询学过「张三」老师授课的同学的信息 SELECT s.*, c.cname, t.tname, sc.score FROM t_mysql_teacher t, t_mysql_course c, t_mysql_student s, t_mysql_score sc WHERE t.tid c.tid AND c.cid sc.cid AND sc.sid s.sid AND t.tname ‘张三’ 02&#x…...
【STM32读取HX711的函数】
[两个普通IO读取HX711数据的函数-主芯片是STM32F407] 以下是.h文件中的内容: #ifndef __hx711_h #define __hx711_h #define HX711CH1_DIO_GROUP GPIOA #define HX711CH1_CLK_GROUP GPIOA #define HX711CH1_DIO_PIN GPIO_Pin_1 #define HX711CH1_CLK_PIN GPIO_Pin…...
MATLAB对数据隔位抽取和插值的几种方法
对于串行的数据,有时我们需要转成多路并行的数据进行处理,抽取;或者是需要对数据进行隔点抽取,或对数据进行插值处理。此处以4倍抽取或插值为例,MATLAB代码实现。 文章目录 抽取方法一:downsample函数方法…...
[NSSCTF Round#16 Basic] CPR
打着玩玩,比赛很简单。 Crypto pr 一个RSA题,n1p*q,n2q*r给了两个c和p,r而且flag经过pad用单因子无法解出。分别用p,r解完再取crt from Crypto.Util.number import * import randomflagplaintext NSSCTF{****************} charset abcdefghijklmn…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
第八部分:阶段项目 6:构建 React 前端应用
现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...
