Python opencv 实现玉米粒计数

Python笔记(一)

(本文用来记录自己学习python的笔记,公开可看,共同学习)

PS:思路就是采用距离变换和找轮廓来实现玉米粒计数和标记优良差

一、调用opencv,numpy库

import cv2
import numpy as np

首先调用两个常见的库opencv和numpy,下面会用到

这两个库需要自行安装:

  1. 安装opencv:命令行输入pip insatll opencv-python
  2. 安装numpy:命令行输入pip install numpy

二、 读入图片

img=cv2.imread(r'C:\Users\30362\Desktop/Corn.jpg')
cv2.imshow('原图',img)

 

cv2.imread('路径'):路径中不能含有中文(如果你使用中文的话python不会报错,但是一但用到这个图片就会立马报错),注意我的路径格式

cv2.imshow():正常图片显示,(图片名称“原图”在python可能显示的是乱码,是因为还需要配置其他库才行)

三、灰度处理

gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度处理
cv2.imshow('gray_img',gray_img)

 

 cv2.cvtColor():色彩空间转换 RGB转GRAY(图像上的灰度值范围为0~255)

四、二值化 

ret,th1=cv2.threshold(gray_img,120,255,cv2.THRESH_BINARY)
cv2.imshow('th1',th1)

 

th1为二值化处理后的图像(图像上的像素点值只有0,255两种) 

120为阈值,大于这个阈值像素点为255(即白色),小于阈值则为0(即黑色),这是默认的,可改;

 

 五、腐蚀变换

erosion = cv2.erode(th1,kernel,iterations = 1)#腐蚀
cv2.imshow('erosion',erosion)

 

cv2.erdoe():对图像进行腐蚀,kernel为卷积核(需自己定义,例kernel = np.ones((7,7),np.uint8))

腐蚀变换的目的是消除噪点(开运算也可以,只是此处要比较是否腐蚀后图上的各个轮廓是否分离,通过上图可以发现仍有粘连,所以就有了下一步——距离变换)

 六、距离变换

dist_img = cv2.distanceTransform(erosion, cv2.DIST_L1, cv2.DIST_MASK_3)#距离变换
cv2.imshow('距离变换',dist_img)
dist_output = cv2.normalize(dist_img, 0, 1.0, cv2.NORM_MINMAX)#归一化
cv2.imshow('dist_output',dist_output*80)

 

cv2.distanceTransform:距离变换(计算图像中像素点到最近零像素点的距离距离变换后得到轮廓的骨架,通过二值化可以有效的去除重叠部分) 

cv2.normalize:归一化(归一化是一种简化计算的方式,即将有量纲的表达式,经过变换,化为无量纲的表达式,成为标量。)

经过归一化得到的图像dist_output灰度值在0~1.0

此处dist_output*80是因为归一化之后灰度值在0~1.0,不容易观察

七、 二值化+开运算

ret,th2=cv2.threshold(dist_output*80,0.3,255,cv2.THRESH_BINARY)
cv2.imshow('th2',th2)
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(th2, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening',opening)

 

灰度处理之后成二值化图像 ,可以发现原本重叠的部分不再重叠,那下面便可以寻找轮廓

八、找轮廓 

opening = np.array(opening,np.uint8)
contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#轮廓提取

 cv2.findContours:轮廓提取,它可以根据你提供的边界点绘制任何形状(注意要寻找的物体为白色背景为黑色)

此函数得到的轮廓集存储在contours里,下面我们进行遍历

九、判断种子优良差 

for cnt in contours:
    (x,y),radius = cv2.minEnclosingCircle(cnt)
    center = (int(x),int(y))
    radius = int(radius)
    circle_img = cv2.circle(opening,center,radius,(255,255,255),1)
    area = cv2.contourArea(cnt)
    area_circle=3.14*radius*radius
    #print(area/area_circle)
    if area/area_circle <=0.5:
        #img = cv2.drawContours(img, cnt, -1, (0,0,255), 5)#差(红色)
        img=cv2.putText(img,'bad',center,font,0.5,(0,0,255))
    elif area/area_circle >=0.6:
        #img = cv2.drawContours(img, cnt, -1, (0,255,0), 5)#优(绿色)
        img=cv2.putText(img,'good',center,font,0.5,(0,0,255))
    else:
        #img = cv2.drawContours(img, cnt, -1, (255,0,0), 5)#良(蓝色)
        img=cv2.putText(img,'normal',center,font,0.5,(0,0,255))
    count+=1
img=cv2.putText(img,('sum='+str(count)),(50,50),font,1,(255,0,0))
cv2.imshow('circle_img',img)
print('玉米粒共有:',count)

 遍历每一个轮廓(for cnt in contours),得到每个轮廓最小外接圆的圆心和半径((x,y),radius = cv2.minEnclosingCircle(cnt))

判断玉米粒优良差标准为每个玉米粒轮廓的面积( area = cv2.contourArea(cnt))与最小外接圆的面积之比

cv2.putText()在指定坐标上写字

最后贴出完整代码 

import cv2
import numpy as np
font=cv2.FONT_HERSHEY_COMPLEX
kernel = np.ones((7,7),np.uint8)
img=cv2.imread(r'C:\Users\30362\Desktop/Corn.jpg')
cv2.imshow('原图',img)
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度处理
cv2.imshow('gray_img',gray_img)
ret,th1=cv2.threshold(gray_img,120,255,cv2.THRESH_BINARY)
cv2.imshow('th1',th1)
erosion = cv2.erode(th1,kernel,iterations = 1)#腐蚀
cv2.imshow('erosion',erosion)
dist_img = cv2.distanceTransform(erosion, cv2.DIST_L1, cv2.DIST_MASK_3)#距离变换
cv2.imshow('距离变换',dist_img)
dist_output = cv2.normalize(dist_img, 0, 1.0, cv2.NORM_MINMAX)#归一化
cv2.imshow('dist_output',dist_output*80)


ret,th2=cv2.threshold(dist_output*80,0.3,255,cv2.THRESH_BINARY)
cv2.imshow('th2',th2)

kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(th2, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening',opening)
opening = np.array(opening,np.uint8)
contours, hierarchy = cv2.findContours(opening,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#轮廓提取
count=0
for cnt in contours:
    (x,y),radius = cv2.minEnclosingCircle(cnt)
    center = (int(x),int(y))
    radius = int(radius)
    circle_img = cv2.circle(opening,center,radius,(255,255,255),1)
    area = cv2.contourArea(cnt)
    area_circle=3.14*radius*radius
    #print(area/area_circle)
    if area/area_circle <=0.5:
        #img = cv2.drawContours(img, cnt, -1, (0,0,255), 5)#差(红色)
        img=cv2.putText(img,'bad',center,font,0.5,(0,0,255))
    elif area/area_circle >=0.6:
        #img = cv2.drawContours(img, cnt, -1, (0,255,0), 5)#优(绿色)
        img=cv2.putText(img,'good',center,font,0.5,(0,0,255))
    else:
        #img = cv2.drawContours(img, cnt, -1, (255,0,0), 5)#良(蓝色)
        img=cv2.putText(img,'normal',center,font,0.5,(0,0,255))
    count+=1
img=cv2.putText(img,('sum='+str(count)),(50,50),font,1,(255,0,0))
cv2.imshow('circle_img',img)
print('玉米粒共有:',count)

先写到这,若有错误或者不足可以提出,共同进步嘻嘻

  • 61
    点赞
  • 271
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用OpenCVPython实现玉米粒计数。首先,需要对图像进行预处理,包括灰度化、二值化、去噪等操作。然后,可以使用轮廓检测算法来检测玉米粒的轮廓,并计算出玉米粒的数量。最后,可以将计数结果显示在图像上,或者保存到文件中。 ### 回答2: OpenCV是一个流行的Python库,专门用于计算机视觉和图像处理任务。在农业领域中,使用OpenCV进行精确的玉米粒计数是非常有用的。 玉米粒计数可以通过许多方法实现,但是使用计算机视觉技术可以准确地计数大量玉米粒。下面是一些使用OpenCV进行玉米粒计数的步骤: 1. 图像获取: 首先需要获取高分辨率的玉米棵图片。一般要求摄影角度正确且相同,并且光线要明亮且均匀。 2. 图像处理:在图像获取后,需要进行一些预处理来让图像更加适合计数。比如可以进行图像二值化、去除噪点等操作。 3. 物体分割: 接下来,需要使用物体分割技术,将每一个玉米粒与图像中的其他物体进行分离。这可以使用图像分水岭或二值化操作实现。 4. 特征提取: 在玉米粒被分离后,需要计算每个玉米粒的面积和周长。这些特征可以帮助我们区分玉米粒和其他物体。 5. 玉米粒计数: 最后,可以对每个玉米粒进行计数。可以使用OpenCV中的连通组件分析或检测每个玉米粒的圆形轮廓并计数。 关于玉米粒计数的项目已经得到了很好的实现,然而,也需要在项目中注意一些注意事项。首先,确保图像质量高且均匀,以避免噪声和不正确的计数。 其次,需要使用影像简化运算来提高计算效率。例如,可以使用图像金字塔或小波变换来简化图像,并加速计算过程。 此外,还需要使用一些高级图像处理技术来区分玉米粒和其他物体,避免因太多干扰物体而导致计数错误。 总结: OpenCV提供了完善和高效的图像处理功能,可用于实现准确和高效的粮食产量测算。用它实现玉米粒计数的方法就如上,这里我们只讲述了其基本步骤。希望这篇文章能给你的农业生产带来一些帮助。 ### 回答3: 随着生产力的提高,许多农场主开始使用计算机视觉技术来提高粮食收割的效率。在农作物收割中,粮食计数是非常重要的一个步骤。OpenCV python库是一种特别适合用于计算机视觉的工具,用来帮助农场主自动计数玉米粒。 首先,我们需要一张图像,这张图像必须是高质量的,清晰的,且包含不同颜色和曲面的玉米粒。在图像处理前,需要将图像像素归一化,这意味着将像素颜色值转换为0到255的等距空间。 然后,我们需要对图像进行预处理。在颜色空间转换之前,可以使用高斯模糊算法进行图像模糊处理,以使图像中玉米粒的边缘变得平滑,以获得更准确的计数结果。接下来,使用色调饱和度值(HSV)颜色空间,此时应该将图像转换为灰度,即只用一种颜色通道进行处理,这使得玉米多少与其颜色无关。灰度处理之后,我们可以通过阈值分割算法(OTSU阈值分割)来提取图像中的玉米粒。这样可以使用轮廓方法(findContours and drawContours)来查找和描绘玉米粒的边界,从而确定玉米粒的轮廓。 一旦得到了玉米粒的轮廓,我们就可以通过基于角度的方法来排除那些不是玉米粒的轮廓。对于符合条件的轮廓,我们就可以统计轮廓的数量来计算玉米粒的总数。 最后,可以将玉米粒的数量和在计数过程中使用的算法进行记录,以便以后可以对算法进行代码改进和性能优化。 综上所述,使用OpenCV python库进行玉米粒计数是一种可行的方法,如果正确处理和优化算法,能够提高粒收割的效率和粮食产量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值