Halcon中对应的例子为novelty_detection_dyn_threshold.hdev,如下:
属于Blob分析中的一个缺陷检测实例,用于检测网格缺陷,如下图所示:
正常网格图例:
缺陷网格图例:
实现步骤:动态二值化,区域面积筛选。Halcon实例代码这里不具体介绍,大家有兴趣按照上面例子名称搜索查看即可,我们根据思路,用OpenCV实现,下面是代码、说明以及最终检测效果演示:
完整源码:
代码语言:javascript复制import numpy as np
import 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 - thresh2
cv2.imshow('thresh',thresh)
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
isNG = False
for 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中宽度大小合适,但是高度偏小,所有代码做了调整如下:
代码语言:javascript复制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)
最终效果展示(左侧原图,右侧结果图):