后面连续几周将开启缺陷检测专题模式,这是第二篇,上篇链接如下,敬请关注!
Halcon缺陷检测实例转OpenCV实现(一)---网格缺陷检测
本期来用OpenCV实现Halcon中一个简单的PCB印刷缺陷检测实例。
Halcon中对应的例子为pcb_inspection.hdev,源图和结果图如下:
Halcon代码比较简单,这里也贴出来,短短13行:
代码语言:javascript复制read_image (Image, 'pcb')
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
* detect defects ...
gray_opening_shape (Image, ImageOpening, 7, 7, 'octagon')
gray_closing_shape (Image, ImageClosing, 7, 7, 'octagon')
dyn_threshold (ImageOpening, ImageClosing, RegionDynThresh, 75, 'not_equal')
dev_display (Image)
dev_set_color ('red')
dev_set_draw ('margin')
dev_display (RegionDynThresh)
实现步骤:对原图做开运算、闭运算然后将二者结果做差,阈值提取。OpenCV的实现我们也参考上面的步骤,详细展示说明如下:
源图:
(1)对源图做开运算:
(2)对源图做闭运算:
(3)开运算和闭运算做差:
(4)对差值图阈值处理:
(5)对阈值图找轮廓并标记结果:
完整代码与注意事项:
代码语言:javascript复制import numpy as np
import cv2
font = cv2.FONT_HERSHEY_SIMPLEX
img = cv2.imread('./pcb.png')
cv2.imshow('src',img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
k1 = np.zeros((7, 7),np.uint8)
pts = np.array([[2,0],[4,0],[6,2],[6,4],[4,6],[2,6],[0,4],[0,2]],np.int32)
pts = pts.reshape((-1,1,2))
cv2.fillPoly(k1,[pts],(1,1,1),cv2.LINE_AA)
k1[5,1] = 1
k1[6,2:5] = 1
print(k1)
opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, k1)
cv2.imshow('opening',opening)
closing = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, k1)
cv2.imshow('closing',closing)
diff = cv2.absdiff(opening, closing)
cv2.imshow('diff',diff)
ret,thresh = cv2.threshold(diff, 80, 255, cv2.THRESH_BINARY)
cv2.imshow('thresh',thresh)
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
isNG = False
if len(contours) > 0:
isNG = True
cv2.drawContours(img,contours,-1,(0,0,255),2)
if isNG:
rect, basline = cv2.getTextSize('Detect NG', font, 1.0, 2)
cv2.rectangle(img, (10,10,int(rect[0]*0.7),rect[1]), (212, 233, 252), -1, 8)
cv2.putText(img,'Detect NG', (10,5 rect[1]), font, 0.7, (0,0,255), 2)
else:
rect, basline = cv2.getTextSize('Detect 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,'Detect OK', (10,5 rect[1]), font, 0.7, (0,200,0), 2)
cv2.imshow('meshDefects', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意Halcon代码中创建的是正八边形结构元素,所以我们也模仿创建如下
代码语言:javascript复制k1 = np.zeros((7, 7),np.uint8)
pts = np.array([[2,0],[4,0],[6,2],[6,4],[4,6],[2,6],[0,4],[0,2]],np.int32)
pts = pts.reshape((-1,1,2))
cv2.fillPoly(k1,[pts],(1,1,1),cv2.LINE_AA)
k1[5,1] = 1
k1[6,2:5] = 1
结构元素输出如下:
为什么用正八边形形状的结构元素,因为PCB的布线图结构和八边形比较类似,如果换矩形结构元素,会多出更多的误判,大家可以自己尝试,对于结构元素的说明以前的文章以详细说明了,这里不做赘述,可参考