Halcon缺陷检测实例转OpenCV实现(一)---网格缺陷检测
Halcon缺陷检测实例转OpenCV实现(二)--- PCB印刷缺陷检测
Halcon缺陷检测实例转OpenCV实现(三)-凸缺陷检测
Halcon缺陷检测实例转OpenCV实现(四)---同色药片缺陷检测
本期文章继续介绍缺陷检测专题的第五个案例,用OpenCV实现Halcon中一个混合颜色缺陷检测的实例,前面案例链接如上↑↑↑。
Halcon中对应的例子为check_blister_mixed.hdev,用于检测替换包装中是否有错的替换或漏装的替代,检测效果如下:
(1)正常情况黄色胶囊3个,红色和绿色胶囊各6个
(2 )异常情况包括漏装,少装和错装
Halcon实例中使用GMM分类方法来实现,GMM(高斯混合模型)常用图像分割分类,某些常见的运动物体检测中的前景和背景分割等,如下:
使用OpenCV实现方法我们用简单的HSV颜色提取和轮廓分析即可,毕竟这个实例中颜色只有3种,我们可以避免准备和训练样本的步骤。当然,如果有更多的颜色或形状的胶囊混合,也可以加一个CNN分类网络来做每一个ROI的识别。我们这里只介绍HSV颜色提取方法,步骤也简单:
(1)设置黄色,红色,绿色的HSV值范围(记得用我上篇文章给大家的工具或自己写个滑动条调试工具),能区分颜色的同时,不要将几种颜色替换;
(2)按照上篇文章的方法,将分割成分段的ROI,然后提取对应的颜色轮廓比对;
(3)比对颜色是否对应,同时轮廓的宽高是否满足要求,然后将每个满足要求的颜色轮廓计数,最后做结果确定即可。
如下是核心代码和运行效果:
(1)HSV颜色取值范围:
lower_yellow = np.array([0,40,40])
upper_yellow = np.array([50,255,255])
lower_red = np.array([0,10,10])
upper_red = np.array([10,255,255])
lower_green = np.array([20,60,50])
upper_green = np.array([80,255,255])
(2)颜色轮廓提取:
hsv_roi=cv2.cvtColor(small_roi,cv2.COLOR_BGR2HSV)
mask_yellow = cv2.inRange(hsv_roi,lower_yellow,upper_yellow)
mask_red = cv2.inRange(hsv_roi,lower_red,upper_red)
mask_green = cv2.inRange(hsv_roi,lower_green,upper_green)
mask_yellow = cv2.medianBlur(mask_yellow, 3)#中值滤波
mask_red = cv2.medianBlur(mask_red, 3)#中值滤波
mask_green = cv2.medianBlur(mask_green, 3)#中值滤波
(3)单个胶囊判断与最终结果判断逻辑:
isRed = isGreen = False
if check_yellow:
#cv2.imshow("mask_yellow",mask_yellow)
contours2,hierarchy2 = cv2.findContours(mask_yellow, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt2 in contours2:
(x2, y2, w2, h2) = cv2.boundingRect(cnt2)
if w2 > 5 and h2 > 5:
cv2.rectangle(img,(x1,y1),(x1+width+5,y1+height+13),(32,165,218),2)
yellow_num = yellow_num + 1
break
## else:
## cv2.rectangle(img,(x1,y1),(x1+width+5,y1+height+13),(0,0,255),2)
## isNG = True
if(len(contours2) < 1):
cv2.rectangle(img,(x1,y1),(x1+width+5,y1+height+13),(0,0,255),4)
isNG = True
if check_red:
contours2,hierarchy2 = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
#cv2.imshow("mask_red",mask_red)
for cnt2 in contours2:
(x2, y2, w2, h2) = cv2.boundingRect(cnt2)
if w2 > 30 and w2 < 60 and h2 > 20 and h2 < 45:
cv2.rectangle(img,(x1,y1),(x1+width+5,y1+height+13),(34,34,178),2)
red_num = red_num + 1
isRed = True
break
if check_green:
#cv2.imshow("mask_green",mask_green)
contours2,hierarchy2 = cv2.findContours(mask_green, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt2 in contours2:
(x2, y2, w2, h2) = cv2.boundingRect(cnt2)
#print(x2, y2, w2, h2)
if w2 > 30 and w2 < 60 and h2 > 20 and h2 < 45:
cv2.rectangle(img,(x1,y1),(x1+width+5,y1+height+13),(35,142,107),2)
green_num = green_num + 1
isGreen = True
break
if not isRed and not isGreen and i>0:
cv2.rectangle(img,(x1,y1),(x1+width+5,y1+height+13),(0,0,255),4)
isNG = True
cv2.putText(img,str(index), (x1,y1), font, 0.7, (255,0,0), 2)
#cv2.imshow("img",img)
#cv2.waitKey()
if yellow_num != 3:
isNG = True
cv2.putText(img,"yellow pillow : %d"%yellow_num, (10,20), font, 0.7, (0,0,255), 2)
else:
cv2.putText(img,"yellow pillow : %d"%yellow_num, (10,20), font, 0.7, (255,255,0), 2)
if red_num != 6:
isNG = True
cv2.putText(img,"red pillow : %d"%red_num, (10,40), font, 0.7, (0,0,255), 2)
else:
cv2.putText(img,"red pillow : %d"%red_num, (10,40), font, 0.7, (255,255,0), 2)
if green_num != 6:
isNG = True
cv2.putText(img,"green pillow : %d"%green_num, (10,60), font, 0.7, (0,0,255), 2)
else:
cv2.putText(img,"green pillow : %d"%green_num, (10,60), font, 0.7, (255,255,0), 2)
print("yellow=%d,red=%d,green=%d"%(yellow_num,red_num,green_num))
运行效果:
核心代码上面已展示,如果对完整原始码作者,欢迎加入知识星球获取,感谢。