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

2020-12-08 09:33:52 浏览数 (1)

后面连续几周将开启缺陷检测专题模式,敬请关注!本期来用OpenCV实现Halcon中一个简单的网格缺陷检测实例。

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)

最终效果展示(左侧原图,右侧结果图):

0 人点赞