java-opencv 米粒数_Python opencv学习音符的米粒数,返回每个米粒的位置面积和总米粒数的平均面积,pythonopencv,笔记,之数,并,一个,及,个数...

之前曾经写过一道数米粒的作业,当时用的是c++中的opencv,这次用python试了一下。

原图及效果图

咦?水印怎么去啊

7d6e6e946b878e911db0121987a83d26.png

3d74462eb47de18cb62f7bd5bcf9afb0.png

aa36ca8348ef0b13c6e0aa1f91cc96ac.png

程序流程

程序的大致流程为:

1.读取图片

2.灰度化

3.二值化

4.膨胀、腐蚀等

5.边缘检测

6.输出

图片读取

用imread加上绝对路径进行读取

# 读取

img_rice = cv2.imread("d:/Python/rice/rice2.jpg")

cv2.imshow('rice', img_rice)

灰度化

基本的灰度化函数

# 灰度化

img_gray = cv2.cvtColor(img_rice, cv2.COLOR_BGR2GRAY)

cv2.imshow('gray', img_rice)

二值化

这个最好画出直方图,从直方图中选取合适的阈值,需要调整

# 二值化

ret,thresh1 = cv2.threshold(img_gray, 123, 255, cv2.THRESH_BINARY)

cv2.imshow('thresh', thresh1)

膨胀、腐蚀

矩阵的结构元素,以及腐蚀、膨胀的迭代次数要注意

# 腐蚀和膨胀

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(2,2)) #定义矩形结构元素

img_erode = cv2.erode(thresh1, kernel, iterations=3)

# cv2.imshow('erode', img_erode)

img_dilated = cv2.dilate(img_erode, kernel)

边缘检测

在边缘检测中对面积进行筛选,如果面积小于20,则认为不是米粒,如果面积大于150,则认为两个粘连,没有分开,具体的参数选取可以输出全部的面积之后再定,比如函数中加入

print(area)

用count统计个数

用ave_area统计面积

# 边缘检测

contours, hierarchy = cv2.findContours(img_dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

count = 0

ave_area = 0

for i in range(len(contours)):

area = cv2.contourArea(contours[i])

if area > 20:

count = count + 1

ave_area = ave_area + area

rect = cv2.boundingRect(contours[i]) #提取矩形坐标

print("number:{} x:{} y:{} area:{}".format(count,rect[0],rect[1], area))#打印坐标

cv2.rectangle(img_rice,rect,(0,255,0),1)#绘制矩形

if area > 150:

count = count + 1

cv2.putText(img_rice,str({count,count-1}), (rect[0], rect[1]), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1) #在米粒左上角写上编号

else:

cv2.putText(img_rice,str(count), (rect[0], rect[1]), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1) #在米粒左上角写上编号

输出

输出总个数和平均面积

ave_area = ave_area / count

# 输出

print('总个数是:{},平均面积是:{}'.format(count,ave_area))

cv2.imshow("Contours", img_rice)

完整代码

完整代码如下:

from cv2 import cv2

# 读取

img_rice = cv2.imread("d:/Python/rice/rice2.jpg")

cv2.imshow('rice', img_rice)

# 灰度化

img_gray = cv2.cvtColor(img_rice, cv2.COLOR_BGR2GRAY)

cv2.imshow('gray', img_rice)

# 二值化

ret,thresh1 = cv2.threshold(img_gray, 123, 255, cv2.THRESH_BINARY)

cv2.imshow('thresh', thresh1)

# 腐蚀和膨胀

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(2,2)) #定义矩形结构元素

img_erode = cv2.erode(thresh1, kernel, iterations=3)

# cv2.imshow('erode', img_erode)

img_dilated = cv2.dilate(img_erode, kernel)

# 边缘检测

contours, hierarchy = cv2.findContours(img_dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

count = 0

ave_area = 0

for i in range(len(contours)):

area = cv2.contourArea(contours[i])

if area > 20:

count = count + 1

ave_area = ave_area + area

rect = cv2.boundingRect(contours[i]) #提取矩形坐标

print("number:{} x:{} y:{} area:{}".format(count,rect[0],rect[1], area))#打印坐标

cv2.rectangle(img_rice,rect,(0,255,0),1)#绘制矩形

if area > 150:

count = count + 1

cv2.putText(img_rice,str({count,count-1}), (rect[0], rect[1]), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1) #在米粒左上角写上编号

else:

cv2.putText(img_rice,str(count), (rect[0], rect[1]), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0, 255, 0), 1) #在米粒左上角写上编号

ave_area = ave_area / count

# 输出

print('总个数是:{},平均面积是:{}'.format(count,ave_area))

cv2.imshow("Contours", img_rice)

cv2.waitKey(0)

cv2.destroyAllWindows()

总结

对于一些米粒粘连严重的图片,这个方法不是很好。但是对于一般的还是可以的,不仅可以用于数米粒,还可以数一些其他的东西,比如玉米粒、芝麻粒、小麦。。。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值