精确分割请看分水岭算法实现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识别图片中的米粒个数,并计算米粒的面积平均面积相关推荐

  1. OpenCV模板匹配识别图片中的数字

    OpenCV模板匹配识别图片中的数字 前言 本博客主要实现利用OpenCV的模板匹配识别图像中的数字,然后把识别出来的数字输出到txt文件中,如果识别失败则输出"读取失败". 操作 ...

  2. python zxing 识别条码_详解利用python识别图片中的条码(pyzbar)及条码图片矫正和增强...

    前言 这周和大家分享如何用python识别图像里的条码.用到的库可以是zbar.希望西瓜6辛苦码的代码不要被盗了.(zxing的话,我一直没有装好,等装好之后再写一篇) 具体步骤 前期准备 用open ...

  3. 如何使用Python识别图片中的二维码

    如何使用Python识别图片中的二维码 二维码是一种方便快捷的信息传递方式,它们广泛应用于电子商务.广告和其他领域.在许多情况下,我们需要识别图片中的二维码,以便从中获取信息.Python是一种流行的 ...

  4. 利用python识别图片中的条码(pyzbar)及条码图片矫正和增强

    利用python识别图片中的条码(pyzbar) 目录 利用python识别图片中的条码(pyzbar) 前言 具体步骤 前期准备 使用pyzbar 特殊情况处理(条码图片矫正和增强) 条码是颠倒的是 ...

  5. 使用 OpenCV 和 Python 识别信用卡号

    使用 OpenCV 和 Python 识别信用卡号 在之前的博文中,我们学习了如何安装 Tesseract 二进制文件并将其用于 OCR. 然后我们学习了如何使用基本的图像处理技术来清理图像以提高 T ...

  6. 如何用Python识别图片中的文字?

    如何用Python识别图片中的文字? 转:https://mp.weixin.qq.com/s/wXDJoAAI8y1mtbUuwATngQ 以下文章来源于微信公众号:新建文件夹X ,作者ZackSo ...

  7. python 识别图片中的中文_python识别图片中文字的方法

    Tesseract 文字识别是ORC的一部分内容,ORC的意思是光学字符识别,通俗讲就是文字识别.Tesseract是一个用于文字识别的工具,我们结合Python使用可以很快的实现文字识别.但是在此之 ...

  8. 使用 OpenCV 和 Python 识别数字

    使用 OpenCV 和 Python 识别数字 本文演示如何使用 OpenCV 和 Python 识别图像中的数字. 在本教程的第一部分,我们将讨论什么是七段显示器,以及我们如何应用计算机视觉和图像处 ...

  9. python识别图片文字_如何利用Python识别图片中的文字

    一.前言 不知道大家有没有遇到过这样的问题,就是在某个软件或者某个网页里面有一篇文章,你非常喜欢,但是不能复制.或者像百度文档一样,只能复制一部分,这个时候我们就会选择截图保存.但是当我们想用到里面的 ...

最新文章

  1. leetcode-125 Valid Palindrome
  2. 太厉害了!推荐几款 Redis 可视化工具
  3. 【论文翻译】Clustering by fast search and find of density peaks
  4. css实现超过两行用...表示
  5. 相濡以沫,不如相忘于江湖
  6. 【预言】鲁迅名言一百年
  7. cmd sqlplus远程连接_sqlplus连接远程数据库
  8. SpringBoot 封装返回类报错:No converter found for return value of type
  9. Highcharts去掉右下角URL水印
  10. 从1.0到2.0:移动互联网入口战升级
  11. 愤怒的小鸟4只编外鸟_愤怒的小鸟2编外怎么得
  12. Word04---字体
  13. 用matlab编写了一个DSP数据处理小软件
  14. python ValueError: source code string cannot contain null bytes
  15. 关于百度APIStore提供的接口调用失败问题
  16. Java项目:律师事务所律师管理系统(java+SSM+HTML+JS+jsp+mysql)
  17. 数据库天才Jim Gray 先生“失踪一年”绝世经典
  18. 路由器映射 局域网开外网设置
  19. 计算机基础实践教程期末考试题库,大一 计算机基础 期末考试题库
  20. Windows 查看文件被哪个进程占用

热门文章

  1. 用python画一个小房子
  2. show running-config命令
  3. Redis基础操作命令
  4. linux下延时函数qt,Qt延时函数
  5. 关于在vs2013中配置opengl红宝书第八版环境
  6. GMT 控制坐标轴标注和网格
  7. Word设置页码格式为共 页 第 页,附带页码不从第一页开始的教程
  8. 系统安全性之数据加密技术
  9. 20962保护和安全
  10. css实现鼠标移入图片,增加遮罩并在上方显示另一个图片