OpenCV For Python识别图片中的米粒个数,并计算米粒的面积平均面积
精确分割请看分水岭算法实现https://blog.csdn.net/qq_36623595/article/details/109273629
使用OpenCV构建图像识别算法,识别图片中的米粒个数,并计算米粒的平均面积和长度
我的开发环境如下
模块版本:OpenCV 4.4.044
版本:Python 3.8.6
编译器:VsCode
下面介绍程序实现:
第一步:图像采集
img = cv2.imread("rice.png")
使用cv2.imread()函数导入图片,括号内输入图片路径,如果图片位于程序所在目录,就可以直接写图片文件名。
第二步:图像预处理
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
主要使用cv2.cvtColor()函数将彩色图片转化为灰度图
第三步:基于灰度的阈值分割
#使用自适应阈值分析进行图像二值化
dst = cv2.adaptiveThreshold(gray,255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,101, 1)
#形态学去噪
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3, 3))
dst=cv2.morphologyEx(dst,cv2.MORPH_OPEN,element) #开运算去噪
使用自适应阈值操作对图像进行二值化,threshold的优点在于可以快速有效的找到类间分割阈值,但其缺点也很明显,就是只能针对单一目标分割,也就是说目标图像的轮廓都属于同一灰度范围,反之可能造成一部分目标探测丢失。
adaptiveThreshold的优点在于可以进行多目标分割,缺点在于基于局部阈值分割出的目标连结性较差,包含噪声。
在这个米粒图片中,下部的图像亮度较暗,如果使用普通阈值操作,下部的米粒将会被认为是背景,而被屏蔽掉。
如图所示:左边是使用局部大津算法,右边是使用全局大津算法,可以看到左边的效果比右边的效果好。
函数官方文档:
cv2. adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
def adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C,dst=None)
参数解释:
src:源图像
maxval:Double类型的,阈值的最大值
adaptiveMethod:Int类型的,这里有两种选择
1 —— ADAPTIVE_THRESH_MEAN_C(通过平均的方法取得平均值)
2 —— ADAPTIVE_THRESH_GAUSSIAN_C(通过高斯取得高斯值)
不过这两种方法最后得到的结果要减掉参数里面的C值thresholdType:Int类型的,方法如下:
THRESH_BINARY 二进制阈值化 -> 大于阈值为1 小于阈值为0
THRESH_BINARY_INV 反二进制阈值化 -> 大于阈值为0 小于阈值为1
THRESH_TRUNC 截断阈值化 -> 大于阈值为阈值,小于阈值不变
THRESH_TOZERO 阈值化为0 -> 大于阈值的不变,小于阈值的全为0
THRESH_TOZERO_INV 反阈值化为0 -> 大于阈值为0,小于阈值不变
blockSize:Int类型的,这个值来决定像素的邻域块有多大。
注意:这里的blockSize的值要为奇数,否则会给出这样的提示:
Assertion failed (blockSize % 2 == 1 && blockSize > 1) in cv::adaptiveThreshold
C:偏移值调整量,计算adaptiveMethod用到的参数。
然后对图像进行形态学去噪,形态学去噪有一下几种:
- 开运算:先腐蚀再膨胀,用来消除小物体
- 闭运算:先膨胀再腐蚀,用于排除小型黑洞
- 形态学梯度:就是膨胀图与俯视图之差,用于保留物体的边缘轮廓。
- 顶帽:原图像与开运算图之差,用于分离比邻近点亮一些的斑块。
- 黑帽:闭运算与原图像之差,用于分离比邻近点暗一些的斑块。
第四步:图像特征描述及目标分析
主要步骤为:
1、检测轮廓- cv2.findContours()函数
2、提取轮廓的水平矩形坐标- rect = cv2.boundingRect( ) 函数
3、绘制矩形- cv2.rectangle()函数
4、 在米粒左上角写上编号-cv2.putText( ) 函
数
1、检测轮廓(函数模型)
cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
参数:
image参数是寻找轮廓的图像;
mode参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):
cv2.RETR_EXTERNAL表示只检测外轮廓(本文使用)
cv2.RETR_LIST检测的轮廓不建立等级关系
cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
cv2.RETR_TREE建立一个等级树结构的轮廓。method参数method为轮廓的近似办法
cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
返回值:
cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
- contour返回值:cv2.findContours()函数首先返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。
- hierarchy返回值:此外,该函数还可返回一个可选的hiararchy结果,这是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0]
~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数。
2、统计米粒的编号、面积、长度
ares = cv2.contourArea(cont)
计算包围形状的面积,并使用一个for循环来计算面积平均值和长度平均值
3、提取轮廓的水平矩形坐标
# 提取矩形坐标(x,y)rect = cv2.boundingRect(cont) # 打印坐标print("x:{} y:{}".format(rect[0],rect[1]))
参数:
- points:输入信息,可以为包含点的容器(vector)或是Mat。
- 返回包覆输入信息的最小正矩形的x,y。
4、绘制矩形
# 绘制矩形cv2.rectangle(img,rect,(0,0,255),1)
参数解释:
- img是原图
- (x,y)是矩阵的左上点坐标
- (x+w,y+h)是矩阵的右下点坐标
- (0,0,255)是画线对应的rgb颜色
- 1是所画的线的宽度
5、 在米粒左上角写上编号
# 防止编号到图片之外(上面),因为绘制编号写在左上角,所以让最上面的米粒的y小于10的变为10个像素y=10 if rect[1]<10 else rect[1] # 在米粒左上角写上编号cv2.putText(img,str(count), (rect[0], y), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1)
各参数依次是:图片输入/添加的文字/左上角坐标/字体/字体大小/颜色/字体粗细
效果图:
完整代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt#? 本程序自适应阈值操作,实现计算米粒参数# 导入图片,图片放在程序所在目录
img = cv2.imread("rice.png")# 转换为灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 使用局部阈值的自适应阈值操作进行图像二值化
dst = cv2.adaptiveThreshold(gray,255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,101, 1)
# res ,dst = cv2.threshold(gray,0 ,255, cv2.THRESH_OTSU)
# 形态学去噪
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3, 3))
# 开运算去噪
dst=cv2.morphologyEx(dst,cv2.MORPH_OPEN,element)
# 轮廓检测函数
contours, hierarchy = cv2.findContours(dst,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
cv2.drawContours(dst,contours,-1,(120,0,0),2)count=0 # 米粒总数
ares_avrg=0 # 米粒平均
# 遍历找到的所有米粒
for cont in contours:# 计算包围性状的面积ares = cv2.contourArea(cont)# 过滤面积小于50的形状if ares<50: continuecount+=1ares_avrg+=ares# 打印出每个米粒的面积print("{}-blob:{}".format(count,ares),end=" ") # 提取矩形坐标(x,y)rect = cv2.boundingRect(cont) # 打印坐标print("x:{} y:{}".format(rect[0],rect[1]))# 绘制矩形cv2.rectangle(img,rect,(0,0,255),1)# 防止编号到图片之外(上面),因为绘制编号写在左上角,所以让最上面的米粒的y小于10的变为10个像素y=10 if rect[1]<10 else rect[1] # 在米粒左上角写上编号cv2.putText(img,str(count), (rect[0], y), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1) # print('编号坐标:',rect[0],' ', y)
print('个数',count,' 总面积',ares_avrg,' ares',ares)
print("米粒平均面积:{}".format(round(ares_avrg/count,2))) #打印出每个米粒的面积cv2.namedWindow("imgshow", 2) #创建一个窗口
cv2.imshow('imgshow', img) #显示原始图片(添加了外接矩形)cv2.namedWindow("dst", 2) #创建一个窗口
cv2.imshow("dst", dst) #显示灰度图cv2.waitKey()
OpenCV For Python识别图片中的米粒个数,并计算米粒的面积平均面积相关推荐
- OpenCV模板匹配识别图片中的数字
OpenCV模板匹配识别图片中的数字 前言 本博客主要实现利用OpenCV的模板匹配识别图像中的数字,然后把识别出来的数字输出到txt文件中,如果识别失败则输出"读取失败". 操作 ...
- python zxing 识别条码_详解利用python识别图片中的条码(pyzbar)及条码图片矫正和增强...
前言 这周和大家分享如何用python识别图像里的条码.用到的库可以是zbar.希望西瓜6辛苦码的代码不要被盗了.(zxing的话,我一直没有装好,等装好之后再写一篇) 具体步骤 前期准备 用open ...
- 如何使用Python识别图片中的二维码
如何使用Python识别图片中的二维码 二维码是一种方便快捷的信息传递方式,它们广泛应用于电子商务.广告和其他领域.在许多情况下,我们需要识别图片中的二维码,以便从中获取信息.Python是一种流行的 ...
- 利用python识别图片中的条码(pyzbar)及条码图片矫正和增强
利用python识别图片中的条码(pyzbar) 目录 利用python识别图片中的条码(pyzbar) 前言 具体步骤 前期准备 使用pyzbar 特殊情况处理(条码图片矫正和增强) 条码是颠倒的是 ...
- 使用 OpenCV 和 Python 识别信用卡号
使用 OpenCV 和 Python 识别信用卡号 在之前的博文中,我们学习了如何安装 Tesseract 二进制文件并将其用于 OCR. 然后我们学习了如何使用基本的图像处理技术来清理图像以提高 T ...
- 如何用Python识别图片中的文字?
如何用Python识别图片中的文字? 转:https://mp.weixin.qq.com/s/wXDJoAAI8y1mtbUuwATngQ 以下文章来源于微信公众号:新建文件夹X ,作者ZackSo ...
- python 识别图片中的中文_python识别图片中文字的方法
Tesseract 文字识别是ORC的一部分内容,ORC的意思是光学字符识别,通俗讲就是文字识别.Tesseract是一个用于文字识别的工具,我们结合Python使用可以很快的实现文字识别.但是在此之 ...
- 使用 OpenCV 和 Python 识别数字
使用 OpenCV 和 Python 识别数字 本文演示如何使用 OpenCV 和 Python 识别图像中的数字. 在本教程的第一部分,我们将讨论什么是七段显示器,以及我们如何应用计算机视觉和图像处 ...
- python识别图片文字_如何利用Python识别图片中的文字
一.前言 不知道大家有没有遇到过这样的问题,就是在某个软件或者某个网页里面有一篇文章,你非常喜欢,但是不能复制.或者像百度文档一样,只能复制一部分,这个时候我们就会选择截图保存.但是当我们想用到里面的 ...
最新文章
- leetcode-125 Valid Palindrome
- 太厉害了!推荐几款 Redis 可视化工具
- 【论文翻译】Clustering by fast search and find of density peaks
- css实现超过两行用...表示
- 相濡以沫,不如相忘于江湖
- 【预言】鲁迅名言一百年
- cmd sqlplus远程连接_sqlplus连接远程数据库
- SpringBoot 封装返回类报错:No converter found for return value of type
- Highcharts去掉右下角URL水印
- 从1.0到2.0:移动互联网入口战升级
- 愤怒的小鸟4只编外鸟_愤怒的小鸟2编外怎么得
- Word04---字体
- 用matlab编写了一个DSP数据处理小软件
- python ValueError: source code string cannot contain null bytes
- 关于百度APIStore提供的接口调用失败问题
- Java项目:律师事务所律师管理系统(java+SSM+HTML+JS+jsp+mysql)
- 数据库天才Jim Gray 先生“失踪一年”绝世经典
- 路由器映射 局域网开外网设置
- 计算机基础实践教程期末考试题库,大一 计算机基础 期末考试题库
- Windows 查看文件被哪个进程占用