基于opencv的大米计数统计(详细处理流程+代码)

2024-01-21

在我每周的标准作业清单中,有一项是编写计算机视觉算法来计算该图像中米粒的数量:

  • 因此,当我的一个好朋友M给我发了一张纸上的扁豆照片(显然是受到上述转发的启发),请我帮他数一下谷物的数量时,它勾起了我怀旧的回忆。因此,我在我的旧硬盘上寻找很久以前编写的代码作为上述问题的参考解决方案。花了一些时间才找到他们。

  • 旧代码是用C 编写的,并使用现已过时的 OpenCV 1.x API。我当前的 PC 中不再安装旧的库版本,而且由于 Python 现在很流行,我决定使用最新的 OpenCV API 将逻辑移植到 Python 3 代码。

  • 在这篇文章中,我将演示实现上述解决方案的非常简单的步骤,解释所做出的一些算法选择、此处介绍的解决方案的一些替代方案和局限性。请注意,这是一个纯粹的计算机视觉算法解决方案。 联系qq1309399183

简化问题

  • 图像中的像素可以取很大范围的值,甚至是代表相同或相似对象的像素。
  • 这给使用经典计算机视觉算法步骤解决图像理解任务带来了特殊的障碍。在我们的输入灰度图像中,值表示 8 位图像表示的各种灰度范围从 0 到255。
  • 将一种类型的对象与另一种类型的对象分开的值的边界并不总是清晰的,并且由于图像采集期间的照明条件,可能具有显着的范围重叠。标准方法是将值减少为几个不同的值,每个值代表有意义的对象。这称为分段。在这种情况下,图像中只有两种类型的区域。一个是属于米粒的像素组,另一个属于背景虚空的像素组。
  • 这是一种非常常见的特殊情况,称为二进制分割,即将输入灰度图像转换为纯黑白形式。纯白色描绘米粒的像素,纯黑色描绘普遍背景。一旦完成,问题就归结为仅仅计算图像中不同的纯白色物体的数量。有多种不同的方法可以实现上述目的。

在这里插入图片描述

正如您可能已经推断出的,这假设可能存在一个特定值,使得所有米粒像素都比该值更亮,而所有背景像素都更暗。为简单起见,我们认为本例中的值为 127(0-255 范围的中间)。但查看输出,我们确实意识到相当多的背景像素已被标记为白色,而许多米粒像素已被标记为黑色。现在的问题是,我们是否必须通过反复试验得出一个合适的阈值,或者是否有更结构化的方法来做到这一点?

thresh, output_binthresh = cv.threshold(input_rice, 127, 255, cv.THRESH_BINARY)
print("固定阈值", thresh)
cv.imshow("二进制阈值(固定)", output_binthresh)

在这里插入图片描述

使用 Otsu 方法进行二元阈值处理
Nobuyuki Otsu 的阈值选择方法(更广泛地称为Otsu 方法)通过最大化类间方差来统计计算合适的阈值。我们可以使用相同的方法来获得更好质量的二值分割结果。

thresh, output_otsuthresh = cv.threshold(input_rice, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
print("大津阈值", thresh)
cv.imshow("二进制阈值 (otsu)", output_otsuthresh)

在这里插入图片描述

  • 上面的结果肯定比以前干净,但仍然不够好。我们可以做得更好吗?答案是肯定的。
  • 如果我们返回并观察原始输入图像,我们可以看到整个图像的照明并不均匀。
  • 中心区域当然是最亮的。它向底部变暗,在某种程度上向顶部和角落也变暗。
  • 由于点光源,这是一种常见的情况。因此,整个图像上的单一阈值可能不是解决二值分割问题的最佳方法。

局部自适应阈值

改变照明的解决方案是需要确定仅适合图像的有限部分的不同阈值。局部自适应阈值的作用是根据像素周围有限矩形区域内像素阴影的分布,为每个像素找到统计上合适的阈值。这抵消了照明梯度。

output_adapthresh = cv.adaptiveThreshold(input_rice,255.0,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,51,-20.0)
cv.imshow("自适应阈值", output_adapthresh)

矩形区域的大小是一个可调参数。有一些直观的过程可以让它正确。我们选择的区域大小为每个像素周围的 51X51 像素,大约是 512X512 图像尺寸的 10%。这似乎适用于我们的输入样本中的缓慢照明变化。对于快速变化的照明,需要较小的区域。
在这里插入图片描述

后期处理

即使使用局部自适应阈值,似乎可以很好地执行二进制分割,但我们在输出中仍然存在一些小问题。在应该有背景的地方有随机的明亮像素斑点。另外,有些谷物对象是连体的,这可能会导致计数结果出现偏差。我们需要清理分割的图像,使其更适合准确计数。

形态侵蚀

侵蚀是一种几何变换,旨在减少又名侵蚀前景形状。我们使用 5 像素矩形算子腐蚀图像。这有助于去除外围斑点。也可以分离出连体的颗粒物体。

kernel = np.ones((5,5),np.uint8)
output_erosion = cv.erode(output_adapthresh, kernel)
cv.imshow(“Morphological Erosion”, output_erosion)

由此产生的输出现在已完全准备好用于我们的计数算法。

数着谷物

正如我之前提到的,通过适当的简化和后处理,看似复杂的问题已简化为仅计算不同纯白色物体的数量。我将提出两种替代方案来完成同样的任务。

连接组件

label_image = output_erosion.copy()
label_count = 0
rows, cols = label_image.shape
for j in range(rows):
    for i in range(cols):
        pixel = label_image[j, i]
        if 255 == pixel:
            label_count += 1
            cv.floodFill(label_image, None, (i, j), label_count)
print("Number of foreground objects", label_count)
cv.imshow("Connected Components", label_image)

在这里插入图片描述

  • 上述逻辑首先系统地寻找白色像素,为它们分配一个唯一的标签 ID(1 到
    254),并递归地为所有相邻的白色像素分配相同的标签,直到覆盖并标记整个不同的对象。
  • 然后继续寻找下一个可用的白色像素 (255),并重复该过程,直到整个图像已处理完毕。分配的唯一标签的数量与不同的前景对象(即米粒)相同。
_, contours, _ = cv.findContours(output_erosion, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
output_contour = cv.cvtColor(input_rice, cv.COLOR_GRAY2BGR)
cv.drawContours(output_contour, contours, -1, (0, 0, 255), 2)
print(“Number of detected contours”, len(contours))
cv.imshow(“Contours”, output_contour)

在这里插入图片描述

  • 轮廓检测逻辑的工作原理是找到前景/背景边界像素,然后执行边界跟随逻辑,以链码的形式对外部轮廓形状进行编码.

  • 执行此操作直到覆盖所有前景对象的边界。检测到的独特外部轮廓的数量与米粒的数量相同。

局限性

上述算法在给定的输入图像上完成其工作,但仍然需要手动调整一些参数。相同的解决方案可能不足以概括到不同的输入或不同的照明条件下。此外,如果图像中颗粒的密度较高,即大多数颗粒彼此相邻或相互遮挡,则这也会严重失败。

最后,↓↓↓↓

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于opencv的大米计数统计(详细处理流程+代码) 的相关文章

  • 如何从opencv中的轮廓中提取简单的几何形状

    我有一个Mat contours我已经近似了每个contour with approxPolyDP 我现在想做的是检测矩形 三角形 圆形等形状 以及例如用不同的颜色或使用画布等重新绘制它们 有没有办法利用轮廓 我如何访问点Mat conto
  • 如何使用python opencv2减去两个图像以获得前景对象

    有没有办法在 python opencv2 中减去两个图像 图片 1 任何图像 例如房屋图像 静态图像 图 2 带有物体的同一图像 在房子里 一个人站着 静态图像 动态物体 图片 3 图片 2 图片 1 如果我们减去Image2 from
  • 使用 Python 和 OpenCV 改善图像歪斜校正

    我生成的用于检测和纠正偏差的代码给了我不一致的结果 我目前正在开展一个项目 该项目利用图像上的 OCR 文本提取 通过 Python 和 OpenCV 因此如果需要准确的结果 消除倾斜是关键 我的代码使用cv2 minAreaRect来检测
  • C++/OpenCV - 用于视频稳定的卡尔曼滤波器

    我尝试使用卡尔曼滤波器稳定视频以进行平滑 但我有一些问题 每次 我都有两帧 一帧是当前帧 另一帧是当前帧 这是我的工作流程 计算 goodFeaturesToTrack 使用 calcOpticalFlowPyrLK 计算光流 只保留优点
  • 使用高斯混合模型进行皮肤检测

    我正在根据以下进行皮肤检测算法本文 http www cc gatech edu rehg Papers SkinDetect IJCV lowres pdf 第 21 页有两个模型 高斯皮肤混合模型和非皮肤颜色模型 第一个皮肤检测模型效果
  • 在进行字符识别之前使用 OpenCV 进行图像预处理(超正方体)

    我正在尝试开发简单的 PC 应用程序用于车牌识别 Java OpenCV Tess4j 图像不是很好 进一步它们会很好 我想对超立方体图像进行预处理 但我被困在车牌检测 矩形检测 上 我的步骤 1 源图像 Mat img new Mat i
  • OpenCV 的 findHomography 产生无意义的结果

    我正在制作一个程序 使用 OpenCV 2 43 中的 ORB 跟踪功能 我遵循并使用了建议从这里 https stackoverflow com questions 9919505 how can i extract fast featu
  • Python OpenCV:检测大体运动方向?

    我仍在编写一个书籍扫描脚本 现在 我所需要的只是能够自动检测翻页 这本书占据了 90 的屏幕 我使用一个粗糙的网络摄像头进行运动检测 所以当我翻页时 运动方向基本上是同一个方向 我修改了一个运动跟踪脚本 但导数却无济于事 usr bin e
  • Matlab 中 interp2 的类似 OpenCV Api

    有没有类似的功能 其工作原理与 interp2 x y frame z xd yd linear 0 在 OpenCV 中 功能cv remap 几乎可以满足您的要求 请参阅文档here http docs opencv org modul
  • 使用 OpenCV 裁剪黑色边缘

    我认为这应该是一个很简单的问题 但我找不到解决方案或有效的关键字进行搜索 我只有这个图像 黑边没有用 所以我想把它们剪掉 只留下 Windows 图标 和蓝色背景 我不想计算Windows图标的坐标和大小 GIMP 和 Photoshop
  • 在opencv中保存帧而不压缩

    我正在尝试使用写 OpenCV 函数 我想保存帧 TIFF扩大 我遇到的问题是保存的图像被压缩 所以我无法使用它们 知道如何摆脱这种压缩吗 提前致谢 不要介意西奇说的话 TIFF 标志通过 LZW 压缩硬编码在 opencv 二进制文件中
  • 如何将 OpenCV 等待键与 Chaquopy 一起使用

    我正在尝试使用 Chaquopy 将计算机视觉应用程序移植到 Android 当我尝试运行脚本时 以下行中出现以下错误 cv2 waitKey 100 打印到嵌入式 python 控制台的错误是 java chaquopy CQPEnv c
  • opencv如何使用compareHist函数

    img cv2 imread mandrill png histg cv2 calcHist img 0 None 256 0 256 if len sys argv lt 2 print gt gt sys stderr Usage sy
  • 如何使用requirements.txt 在 Heroku python Web 应用程序中安装 Dlib?

    我构建了一个涉及机器学习的 Python Flask Web API 但在 Heroku 上部署它时遇到了很多挫折 问题是 我的应用程序依赖于 Dlib 一个库 我似乎找不到在我的 Heroku 服务器中安装的方法 我正在试图解决这个问题
  • 如何使图像呈现出陈旧、布满灰尘、颜色褪色的外观?

    我有旧画的图像 这些画很旧 布满灰尘 颜色褪色 如图所示here https i stack imgur com xuoEF jpg 如何赋予任何图像这种 旧 外观 我找不到任何过滤器或 openCV 函数来实现这种类型的外观 EDIT 我
  • 如何解决 Python 'Pyzbar' 库的导入错误?

    我刚刚开始熟悉 Pyzbar 库 但是当使用decode方法我得到一个错误 这是代码 import cv2 import numpy as np import pyzbar code image cv2 imread C Users Ace
  • OpenCV findContours 破坏源图像

    我编写了一个在单通道空白图像中绘制圆形 直线和矩形的代码 之后 我只需找出图像中的轮廓 就可以正确获取所有轮廓 但找到轮廓后 我的源图像变得扭曲 为什么会出现这种情况 任何人都可以帮我解决这个问题 我的代码如下所示 using namesp
  • 在 Python 3.5 64 位上通过 pip 安装 OpenCV

    我尝试安装 OpenCV 但找不到任何合适的 pip 软件包 我决定上网查找有关如何安装它的官方文档 并发现this https opencv python tutroals readthedocs io en latest py tuto
  • CvMat 和 Imread 与 IpImage 和 CvLoadImage

    使用 OpenCv 2 4 我有两个选项来加载图像 1 CvMat and Imread 2 IpImage and CvLoadImage 使用哪一个更好 我尝试将两者混合并最终出现段错误 imread返回一个Mat not CvMat
  • brew 链接 jpeg 问题

    我正在尝试安装opencv在 Mac OSX Lion 上 brew install opencv 我收到以下错误 以及其他一些类似的错误 Error The linking step did not complete successful

随机推荐

  • 如何写好一个错误报告

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 一篇文章带你了解Python常用自动化测试框架——Pytest

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • Vue3 和Vue2的区别,以及钩子函数的使用

    Vue js 3 和 Vue js 2 是两个主要版本的流行前端框架 它们之间有很多区别 包括性能优化 新特性和改进的API等 以下是一些Vue 3与Vue 2之间的主要区别 以及一些示例代码来说明这些差异 1 性能优化 响应式系统 Vue
  • Jmeter 性能-阶梯式性能指标监听

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • Jmeter 性能-阶梯负载最终请求数

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • msyql 异常,别干着急,70%的问题都在这里!

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 摸爬滚打多年的打工人,总结了三条职场真理,绝不假大空!

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 低代码-添加按钮组件设计

    效果图 可拆分为以下细节 按钮列表 删除 两个操作需同步删除 点击外侧删除 点击复选框删除 添加 点击复选框添加 示例代码 技术栈 vue3 arco design ts less tailwindcss
  • 低代码配置-组件列表设计

    过滤字段功能 配置了api 启用 输出配置 filter type Array default gt
  • 活动日程&直播预约|智谱AI技术开放日 Zhipu DevDay

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 直播预约通道 关于AI TIME AI TIME源起于2019年 旨在发扬科学思辨精神 邀请各界人士对人工智能理论 算法和场景应用的本质问题进行探索 加强思想碰撞 链接全球AI学
  • 【ES6】解构语句中的冒号(:)

    在解构赋值语法中 冒号 的作用是为提取的字段指定一个新的变量名 让我们以示例 const billCode code version route query 来说明 billCode code version 表示从 route query
  • 低代码配置-列表页组件设计

    保存 表单属性存放 bill 筛选项配置存放 filterLayout 列表按钮存放 buttonLayout 列表布局存放 listLayout api存放 api 数据结构 layout 存放表单基础配置 bill 存放按钮基础配置 b
  • 明日 15:00 | NeurIPS 2023 Spotlight 论文

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 哔哩哔哩直播通道 扫码关注AITIME哔哩哔哩官方账号预约直播 1月17日 15 00 16 00 讲者介绍 黄若孜 腾讯AI LAB游戏AI研究员 2020年复旦大学硕士毕业后
  • 直播预告 | Robust Model Diagnostics 杨耀青团队专场 | 1月19日 10:00

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 哔哩哔哩直播通道 扫码关注AITIME哔哩哔哩官方账号预约直播 1月19日 10 00 10 10 杨耀青 达特茅斯学院助理教授 卡内基梅隆大学博士 清华大学学士 研究领域是机器
  • 开眼了,自动化测试还能这样用?

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 低代码-详情页组件设计

    效果图 详情页数据结构定义 layout 按钮数据 buttonLayout headButton 页头按钮 footButton 页脚按钮 详情页表单配置 config 配置组件列表 detailLayout 默认行为 进表单初始化 只展
  • 新手也能看懂的【前端自动化测试入门】

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 多模态、长文本、智能体,智谱AI推出GLM-4模型全家桶,发布即上线!

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 2024年01月16日 智谱AI首届技术开放日 Zhipu DevDay 在北京中关村国家自主创新示范区展示中心成功举办 现场 智谱AI团队全面展示了其投身于大模型事业三年多来所
  • 动物姿态识别+数据集+代码

    目录 一级目录 二级目录 三级目录 介绍 关键点定义 背景 环境安装 安装
  • 基于opencv的大米计数统计(详细处理流程+代码)

    在我每周的标准作业清单中 有一项是编写计算机视觉算法来计算该图像中米粒的数量 因此 当我的一个好朋友M给我发了一张纸上的扁豆照片 显然是受到上述转发的启发 请我帮他数一下谷物的数量时 它勾起了我怀旧的回忆 因此 我在我的旧硬盘上寻找很久以前