后面连续几周将开启缺陷检测专题模式,敬请关注!本期来用OpenCV实现Halcon中一个简单的网格缺陷检测实例。
Halcon中对应的例子为novelty_detection_dyn_threshold.hdev,如下:
属于Blob分析中的一个缺陷检测实例,用于检测网格缺陷,如下图所示:
正常网格图例:
缺陷网格图例:
实现步骤:动态二值化,区域面积筛选。Halcon实例代码这里不具体介绍,大家有兴趣按照上面例子名称搜索查看即可,我们根据思路,用OpenCV实现,下面是代码、说明以及最终检测效果演示:
完整源码:
import numpy as npimport cv2
font = cv2.FONT_HERSHEY_SIMPLEX
img = cv2.imread('./imgs/plastic_mesh_01.png')cv2.imshow('src',img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (3,3), 1.0)
#ret,thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)_,thresh1 = cv2.threshold(gray, 25, 255, cv2.THRESH_BINARY_INV )_,thresh2 = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY_INV )thresh = thresh1 - thresh2cv2.imshow('thresh',thresh)
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
isNG = Falsefor cnt in contours: area = cv2.contourArea(cnt)if(area>350): cv2.drawContours(img,cnt,-1,(0,0,255),2) isNG = True# else:# cv2.drawContours(img,cnt,-1,(0,255,0),1)
if isNG: rect, basline = cv2.getTextSize('Mesh Not OK', font, 1.0, 2) cv2.rectangle(img, (10,10,int(rect[0]*0.7),rect[1]), (212, 233, 252), -1, 8) cv2.putText(img,'Mesh Not OK', (10,5+rect[1]), font, 0.7, (0,0,255), 2)else: rect, basline = cv2.getTextSize('Mesh OK', font, 1.0, 2) cv2.rectangle(img, (10,10,int(rect[0]*0.7),rect[1]), (212, 233, 252), -1, 8) cv2.putText(img,'Mesh OK', (10,5+rect[1]), font, 0.7, (0,200,0), 2) cv2.imshow('meshDefects', img)cv2.waitKey(0)cv2.destroyAllWindows()
代码简单说明:
(1) 关于阈值方法,首先尝试了OTSU方法,后面发现有部分正常孔洞和网格会相连,如下图所示,导致正常孔洞也被标记为缺陷(第三幅图);
后面改为了区间阈值方法,这部分测试图阈值相对稳定,故可用,区间阈值方法可参考这篇文章介绍Halcon实例转OpenCV之实现给定区间二值化
更改为区间阈值后实现的效果:
(2) 根据面积来标记缺陷区域,先大概统计一下正常孔洞区域的面积范围,然后设置缺陷区域面积大于正常范围的最大值即可;
(3)关于putText结果标记这里配合getTextSize()函数来使用,此函数是用来获取字体尺寸大小的,但是绘制出来不能完整的将文字包围,获取文字区域的Rect中宽度大小合适,但是高度偏小,所有代码做了调整如下:
rect, basline = cv2.getTextSize('Mesh Not OK', font, 1.0, 2)cv2.rectangle(img, (10,10,int(rect[0]*0.7),rect[1]), (212, 233, 252), -1, 8)cv2.putText(img,'Mesh Not OK', (10,5+rect[1]), font, 0.7, (0,0,255), 2)
最终效果展示(左侧原图,右侧结果图):
|