计算机视觉 | 基于图像处理和边缘检测算法的黄豆计数实验

目录

  • 一、实验原理
  • 二、实验步骤
    • 1. 图像读取与预处理
    • 2. 边缘检测
    • 3. 轮廓检测
    • 4. 标记轮廓序号
  • 三、实验结果

Hi,大家好,我是半亩花海。 本实验旨在利用 Python 和 OpenCV 库,通过图像处理边缘检测算法实现黄豆图像的自动识别和计数,并在图像上标记每个黄豆的轮廓序号

一、实验原理

  • 灰度转换:将彩色图像转换为灰度图像,减少计算复杂度。
  • 高斯平滑:使用高斯模糊来减少图像噪声。
  • Canny边缘检测:检测图像中的边缘。
  • 轮廓查找:使用OpenCV的findContours函数检测图像中的轮廓。
  • 绘制轮廓和标记:在原始图像上绘制检测到的轮廓,并标记每个轮廓的序号。

二、实验步骤

1. 图像读取与预处理

import cv2
import matplotlib.pyplot as plt# 读取图像
image = cv2.imread('soybean.jpg')# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 平滑处理
blurred = cv2.GaussianBlur(gray, (11, 11), 0)

soybean.jpg 图片如下所示,可自取:

2. 边缘检测

  • cv2.Canny(blurred, 30, 150):使用Canny算法进行边缘检测,参数30和150分别是低阈值和高阈值。
# 使用Canny边缘检测
edges = cv2.Canny(blurred, 30, 150)

3. 轮廓检测

  • cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE):查找图像中的轮廓。RETR_EXTERNAL表示只检测外部轮廓,CHAIN_APPROX_SIMPLE表示使用简单的链式近似方法。
# 查找轮廓
contours, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

4. 标记轮廓序号

  • cv2.boundingRect(contour):计算轮廓的边界框,用于确定标注位置。
  • cv2.drawContours(image, [contour], -1, (0, 255, 0), 2):绘制轮廓,绿色线条,线宽为2像素。
  • cv2.putText(image, str(i + 1), (x + w // 2, y + h // 2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2):在每个轮廓的中心位置标注序号,红色字体,字体大小为0.5,线宽为2像素。
# 绘制轮廓并标记序号
for i, contour in enumerate(contours):# 计算轮廓的边界框,用于确定标注位置x, y, w, h = cv2.boundingRect(contour)# 绘制轮廓cv2.drawContours(image, [contour], -1, (0, 255, 0), 2)# 在轮廓内标注序号cv2.putText(image, str(i + 1), (x + w // 2, y + h // 2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)

三、实验结果

  • plt.figure(figsize=(10, 10)):创建一个显示窗口,大小为10x10英寸。
  • plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)):将处理后的图像转换为RGB格式并显示。
  • plt.axis(‘off’):关闭坐标轴显示。
  • plt.show():显示图像。
  • print(f"黄豆数量: {len(contours)}"):输出检测到的黄豆数量。
# 显示结果图像
plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()# 输出黄豆数量
print(f"黄豆数量: {len(contours)}")

实验结果表明:图像中的所有18个黄豆都被成功识别和标记,每个黄豆的轮廓被绿色线条清晰绘制,序号标记在轮廓中心位置附近。

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

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

相关文章

ICMPV6协议

ICMPV6:intermet 控制管理协议--- 存在大量的子协议 1、PMTU---路径 MTU 发现协议 通过ICMPV6error包来获取整段路径上最小 MTU 值 2、NDP------邻居发现协议---用于取代IPV4下的 ARP协议 假设PC1和PC2 通讯 1无2的MAC地址 …

JetBrains GoLand 2024 mac/win版:高效开发,Go无止境

JetBrains GoLand 2024是一款专为Go语言开发者设计的集成开发环境(IDE),为开发者带来了更加高效、智能和便捷的编程体验。 GoLand 2024 mac/win版获取 在代码编辑方面,GoLand 2024提供了全行代码补全功能,通过利用先进的深度学习模型&#x…

C#面:C#中的析构函数是什么?

在C#中,析构函数是一种特殊的方法,用于在对象被销毁之前执行一些清理操作。它的名称与类名相同,但在名称前面加上一个波浪线(~)。析构函数没有参数,也没有返回类型。 当对象不再被使用时,垃圾回…

力扣85.最大矩形

力扣85.最大矩形 遍历所有行作为底边 做求矩形面积&#xff08;84. class Solution {public:int maximalRectangle(vector<vector<char>>& matrix) {if (matrix.empty()) return 0;int n matrix.size(),m matrix[0].size();int res0;vector<int> li…

grub引导LinuxMint

注意事项&#xff1a;文件系统必须是FAT32 安装 sudo apt install gparted -y 分区管理软件 使用gparted分区和查看设备路径 sudo apt-get install grub-efi-amd64 #/dev/sdd1 是需要制作分区引导的设备路径 sudo mount /dev/sdd1 /mnt/123 #bios sudo grub-install --targe…

适耳贴合的气传导耳机,带来智能生活体验,塞那Z50耳夹耳机上手

现在大家几乎每天都会用到各种AI产品&#xff0c;蓝牙耳机也是我们必不可少的装备&#xff0c;最近我发现一款很好用的分体式气传导蓝牙耳机&#xff0c;它还带有一个具备AI功能的APP端&#xff0c;大大方便了我们日常的使用。这款sanag塞那Z50耳夹耳机我用过一段时间以后&…

interface Ref<T = any> 这是什么写法?为什么写接口还需要加上<T = any>

问: export interface Ref<T any> { value: T [RefSymbol]: true } 这里既然是interface接口,为什么还有<T any>这是什么意思? 回答: <T any> 中的 <T> 表示这是一个泛型参数&#xff0c;它可以在接口中作为类型的占位符&#xff0c;在实际…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-19图像卷积

19图像卷积 #互相关运算 #在卷积层中&#xff0c;输入张量和核张量通过互相关运算产生输出张量。 import torch from torch import nn from d2l import torch as d2ldef corr2d(X, K):"""计算二维互相关运算"""h, w K.shapeY torch.zeros((X.…

开发指南033-数据库兼容

元芳&#xff0c;你怎么看&#xff1f; 单一数据库自身就有一些不同处理之处&#xff0c;如果一个平台要兼容所有数据库&#xff0c;就是难上加难&#xff0c;像isnull函数各数据库就不同。 对于这类问题&#xff0c;平台采用统一自定义函数解决&#xff0c;例如上面的round函…

一篇文章搞懂残差网络算法

残差网络(Residual Network,简称ResNet)是一种深度学习架构,它在2015年由微软研究院的Kaiming He等四位作者提出。ResNet的提出是为了解决深度神经网络训练中的梯度消失和梯度爆炸问题,以及随着网络层数增加而出现的性能退化问题。本文将详细介绍残差网络算法的定义、产生…

模式分解的概念(下)-无损连接分解的与保持函数依赖分解的定义和判断、损失分解

一、无损连接分解 1、定义 2、检验一个分解是否是无损连接分解的算法 输入与输出 输入&#xff1a; 关系模式R&#xff08;U&#xff0c;F&#xff09;&#xff0c;F是最小函数依赖集 R上的一个分解 输出&#xff1a; 判断分解是否为无损连接分解 &#xff08;1&#x…

【LinuxC语言】POSIX信号量

文章目录 前言一、信号量的概念信号量相关函数sem_initsem_waitsem_postsem_destroy总结前言 在并发编程中,我们经常需要对共享资源进行访问控制,以防止数据竞争和不一致性。在Linux C语言中,我们使用一种称为“信号量”的机制来实现这种控制。信号量是一种同步工具,用于保…

JAVA同城服务场馆门店预约系统支持H5小程序APP源码

&#x1f4f1;一键预约&#xff0c;畅享无忧体验&#x1f3e2; &#x1f680;一、开启预约新纪元 在繁忙的都市生活中&#xff0c;我们常常因为时间紧张而错过心仪的门店或场馆服务。然而&#xff0c;有了“门店场馆预约小程序”&#xff0c;这些问题都将迎刃而解。这款小程序…

群辉NAS中文件下载的三种方案

目录 一、迅雷套件 1、添加套件来源 2、安装套件 3、手机安装迅雷 二、qBittorrent套件 1、添加套件来源 2、改手工安装 3、更新后的问题 4、最后放弃DSM6 (1)上传文件手工安装 (2)添加套件来源 5、解决登陆报错 6、添加tracker 7、修改下载默认位置 8、手机…

c++之说_15|成员函数的const尾缀修饰 ( const const)

我记得我刚接触c的时候 遇到成员函数 右边尾部 写了个const 我当时就很蒙 不过慢慢的也从大佬口中获得一二经验了 class kj{public:void get(){printf("无修饰\n");}void get()const{printf("const 修饰\n");}}; 大概就是这个样子 当时我抓耳挠腮的看…

代码随想录算法训练营第45天 [ 198.打家劫舍 213.打家劫舍II 337.打家劫舍III ]

代码随想录算法训练营第45天 [ 198.打家劫舍 213.打家劫舍II 337.打家劫舍III ] 一、198.打家劫舍 链接: 代码随想录. 思路&#xff1a; dp[i]表示偷第i间房能获得的最大价值为dp[i] dp[0] nums[0] dp[1] max(nums[0],nums[1]) dp[i] max(dp[i-2]nums[i],dp[i-1]) 做题状态&…

【yolov8语义分割】跑通:下载yolov8+预测图片+预测视频

1、下载yolov8到autodl上 git clone https://github.com/ultralytics/ultralytics 下载到Yolov8文件夹下面 另外&#xff1a;现在yolov8支持像包一样导入&#xff0c;pip install就可以 2、yolov8 语义分割文档 看官方文档&#xff1a;主页 -Ultralytics YOLO 文档 还能切…

图扑助力铝型材挤压:数字孪生引领智慧管理

通过图扑数字孪生技术&#xff0c;为铝型材挤压车间提供实时监控和优化管理方案。高精度三维建模和数据可视化提升了生产效率和管理透明度&#xff0c;推动智能制造和资源优化配置。

leetcode 二分查找·系统掌握 寻找旋转排序数组中的最小值II

题目&#xff1a; 题解&#xff1a; 本题比普通的寻找旋转排序数组中的最小值多了一个数组中的元素可以重复这一点。 这会时原来的思路出现一个漏洞&#xff08;大家感兴趣可以看看我做普通版寻找旋转排序数组最小值的思路&#xff09;&#xff0c;就是旋转后的数组中的第二个…

cas客户端流程详解(源码解析)--单点登录

博主之前一直使用了cas客户端进行用户的单点登录操作&#xff0c;决定进行源码分析来看cas的整个流程&#xff0c;以便以后出现了问题还不知道是什么原因导致的 cas主要的形式就是通过过滤器的形式来实现的&#xff0c;来&#xff0c;贴上示例配置&#xff1a; 1 <list…