Halcon缺陷检测实例转OpenCV实现(二)

2020-12-22 09:50:03 浏览数 (1)

后面连续几周将开启缺陷检测专题模式,这是第二篇,上篇链接如下,敬请关注!

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的布线图结构和八边形比较类似,如果换矩形结构元素,会多出更多的误判,大家可以自己尝试,对于结构元素的说明以前的文章以详细说明了,这里不做赘述,可参考

O

0 人点赞