python毒酒检测_opencv Python 瓶子篓错误点检测

本文介绍了一个使用Python和OpenCV检测瓶子篓中错误的小项目,包括透视变换、裁剪、自适应均衡化等步骤,以识别未摆放瓶子、瓶子带盖等问题,并在图像上标注错误点。
摘要由CSDN通过智能技术生成

瓶子篓错误点检测

这是最近在课程作业中做的小项目,放在这里和大家分享一下。

主要任务:

检测出瓶子篓中存在错误的地方(如:未摆放瓶子、瓶子带盖、瓶子横着放置、瓶子上放有塑料杯等)并将这些错误分别标识出来。

f504edd5dfe1e83ecb16bfede96d436b.png

主要步骤:

1、透视变换 2、裁剪 3、自适应均衡化 4、阈值分割 5、腐蚀膨胀 6、寻找目标轮廓 7、画轮廓最小外接矩形 8、显示图像

1、导入功能包,定义相关函数

import numpy as np

from imutils.perspective import four_point_transform

import imutils

import cv2

def cv_show(name, img): cv2.imshow(name,img) cv2.waitKey(0) #cv2.destroyAllWindows()

def Get_Outline(input_dir): image = cv2.imread("Resources/bottle_crate_01.png") #读图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #原图转灰度图 blurred = cv2.GaussianBlur(gray, (5,5),0) #高斯模糊 edged = cv2.Canny(blurred,75,200) #canny边缘检测 return image,gray,blurred,edged

)1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

2、透视变换

说明:需要检测的这一组图像中,感兴趣的是中间的部分,图像中的背景和篓子的外框都是需要去除的。而瓶子篓有的摆的比较正,有的存在一定倾斜角度,所以单纯使用裁剪工具并不能对所有的图像奏效,不具有普适性。因为篓子的外框比较好检测,所以可以使用透视变换,通过检测出篓子的外框轮廓,从而找到四个角点进行四点透视变换。效果如下图所示(左为原图,右为透视变换效果图)。

##透视变换

#找透视变换的轮廓

def Get_cnt(edged): cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) cnts = cnts[1] if imutils.is_cv2() else cnts[0] docCnt =None if len(cnts) > 0: cnts =sorted(cnts,key=cv2.contourArea,reverse=True) for c in cnts: peri = cv2.arcLength(c,True) # 轮廓按大小降序排序 approx = cv2.approxPolyDP(c,0.02 * peri,True) # 获取近似的轮廓 if len(approx) ==4: # 近似轮廓有四个顶点 docCnt = approx break return docCnt

if __name__=="__main__": input_dir = "Resources/bottle_crate_06.png" image,gray,blurred,edged = Get_Outline(input_dir) docCnt = Get_cnt(edged) result_img = four_point_transform(image , docCnt.reshape(4,2)) # 对原始图像进行四点透视变换

cv_show('image', image)

#cv_show('gray', gray)

#cv_show('blurred', blurred)

#cv_show('edged', edged)

cv_show('result_img', result_img) #透视变换后的结果1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

bf844e508d0049bc00ad4f66a06e124e.png

3、裁剪

说明:透视变换之后的图像中左右边缘仍有部分反光较严重的地方,会对后面的二值化及开运算处理产生影响,因此可以裁剪掉。效果如下图。

Cropped = result_img[10:375,25:560]

#print(Cropped.shape)

#cv_show('Cropped', Cropped)1

2

3

c8794bc4a76b78c5f6561a2d065daf76.png

4、自适应均衡化

说明:由于整个图像光线较暗,对比度太低,所以需要均衡化处理,而普通的直方图均衡化会使得图片曝光过亮,局部细节丢失,因此选择自适应均衡化处理,效果如下(左边为原图,中间为自适应均衡化,右边为直方图均衡化)。

#自适应均衡化

Cropped_gray = cv2.cvtColor(Cropped, cv2.COLOR_BGR2GRAY) #转灰度图

clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))

cll = clahe.apply(Cropped_gray)

cv_show('cll', cll)1

2

3

4

5

4f0bf7f0774f9f593840b264d2f60518.png

5、阈值分割

以图10为例

#二值化处理

rst,th = cv2.threshold(cll, 120, 255, cv2.THRESH_BINARY)

cv_show('th', th)1

2

3

076f40818db48b41085410c7b09a7364.png

6、腐蚀膨胀

#腐蚀

kernel=np.ones((8,8),np.uint8)

imgEroded=cv2.erode(th,kernel,iterations=1)

cv_show('imgEroded', imgEroded)

#膨胀

imgDialation=cv2.dilate(imgEroded,kernel,iterations=1)

cv_show('imgDialation', imgDialation)1

2

3

4

5

6

7

30475df9dffc0823130ff05ff99e0c41.png

7、寻找并画出目标轮廓

说明:形态学处理完成后,设定参数值,进行目标寻找。(这里将参数像素和设定为35效果较好)

#找目标轮廓

(cnts,_) = cv2.findContours(imgDialation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

#画轮廓

list=[]

imgDialation_RGB=cv2.cvtColor(imgDialation, cv2.COLOR_GRAY2BGR)

for cnt in cnts:

(x, y, w, h) = cv2.boundingRect(cnt)

print(x, y, w, h)

if w > 35: cv2.drawContours(imgDialation_RGB,cnt,-1,(0,0,255),2) isNG = True list.append(cnt)

a=len(list) #目标数量

print(a)1

2

3

4

5

6

7

8

9

10

11

12

13

14

47da7bf74fba6d96e270a666c415a18f.png

263187eef1fc9b363f3360f6a53aeaf4.png

说明:这一步效果并不是十分好,可以从图中看出,在进行形态学处理时有部分原本连通的区域被断开了,导致轮廓识别时被识成了两个甚至多个轮廓。

8、画轮廓最小外接矩形并在图上显示

说明:找出目标(即错误点)的轮廓后通过cv2.minAreaRect()函数可以找到轮廓的最小外接矩形,通过cv2.drawContours()函数将其画出。通过cv2.putText()函数可将文字信息在图上直观地表示出来。如果图像没有错误,则显示“Good”,如果发现错误,则显示"Not Good"。

#如果目标数量大于零(即有故障)

if a>0: cv_show('imgDialation_RGB', imgDialation_RGB) print("NOT GOOD") #Cropped_RGB = cv2.cvtColor(Cropped, cv2.COLOR_GRAY2BGR) # 画目标轮廓的最小外接矩形 for cnt in list: rect = cv2.minAreaRect(cnt) box = np.int0(cv2.boxPoints(rect)) img = cv2.drawContours(Cropped, [box], -1, (0, 255, 0), 3) cv2.putText(img, "Not Good", (40, 40), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 150, 0), 3) cv_show("Img", img) #cv2.imwrite("contoursImage2.jpg", image)

else: #无故障 cv2.putText(image, "Good", (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0, 150, 0), 5) cv_show("image", image) print("GOOD") #无故障1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

b386940920dce6c92e9bf94fb3c3a3b3.png

以上就是bottle_crate的检测实现过程,其中还有一些小问题有待改进。如果有更好的方案的欢迎留言~

文章来源: blog.csdn.net,作者:PURSUIT_0119,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_43544490/article/details/112801494

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值