点击上方“小白学视觉”,选择加"星标"或“置顶”
今天来一个缺陷检测的实例,如下是原图,第二个和第三个黑色部件有缺陷
思路:
①提取OK部件轮廓做model
②遍历部件轮廓,做差分,形态学处理
③结果判断绘制
上代码(含注释):
import cv2
import numpy as np
# 获取模板ROI
def get_template(binary, boxes):
x, y, w, h = boxes[0]
roi = binary[y:y+h, x:x+w]
return roi
def detect_defect(binary, boxes, tpl):
global src
height, width = tpl.shape
index = 1
defect_rois = []
# 发现缺失
for x, y, w, h in boxes:
roi = binary[y:y + h, x:x + w]
roi = cv2.resize(roi, (width, height))
mask = cv2.subtract(tpl, roi)
se = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5), (-1, -1))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, se)
ret, mask = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY)
mask, contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
color_mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
cv2.drawContours(color_mask, contours, -1, (0, 255, 255), -1, 8)
mask_roi = src[y:y + height, x:x + width]
cv2.bitwise_or(color_mask, mask_roi, mask_roi, mask = mask)
count = 0
for row in range(height):
for col in range(width):
pv = mask[row, col]
if pv == 255:
count += 1
if count > 0:
defect_rois.append([x, y, w, h])
else:
cv2.rectangle(src, (x, y), (x+w, y+h), (0, 255, 0), 2, 8, 0)
cv2.putText(src, "OK", (x, y - 2), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.imwrite("mask%d.png"%index, mask)
index += 1
return defect_rois
global src
src = cv2.imread("1.jpg")
cv2.imshow("input", src)
# 图像二值化
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# 形态学开运算
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3), (-1, -1))
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, se)
cv2.imshow("binary", binary)
# 轮廓提取
out, contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
height, width = src.shape[:2]
rects = []
# 轮廓筛选
for c in range(len(contours)):
# 轮廓外接矩形
x, y, w, h = cv2.boundingRect(contours[c])
# 轮廓面积
area = cv2.contourArea(contours[c])
if h > (height//2):
continue
if area < 150:
continue
rects.append([x, y, w, h])
# 排序轮廓(按照rect中y值排序也就是纵坐标从小到大)
rects = sorted(rects, key = lambda x:x[1])
for i in range(len(rects)):
print(rects[i])
# 获取模板ROI
template = get_template(binary, rects)
cv2.imshow("template", template)
# 填充边缘
for c in range(len(contours)):
x, y, w, h = cv2.boundingRect(contours[c])
area = cv2.contourArea(contours[c])
if h > (height//2):
continue
if area < 150:
continue
cv2.drawContours(binary, contours, c, (0), 2, 8)
# 检测缺陷
defect_boxes = detect_defect(binary, rects, template)
for dx, dy, dw, dh in defect_boxes:
cv2.rectangle(src, (dx, dy), (dx + dw, dy + dh), (0, 0, 255), 2, 8, 0)
cv2.putText(src, "NG", (dx, dy-2), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)
index = 1
for dx, dy, dw, dh in rects:
cv2.putText(src, "No.%d"%index, (dx-60, dy+30), cv2.FONT_HERSHEY_SIMPLEX, .7, (255, 0, 255), 2)
index += 1
cv2.imshow("result", src)
cv2.imwrite("binary2.png", src)
cv2.waitKey(0)
cv2.destroyAllWindows()
其中76,77行说明:
# 排序轮廓(按照rect中y值排序也就是纵坐标从小到大)
rects = sorted(rects, key = lambda x:x[1]
最终检测效果(红色标注NG部件,黄色标注缺陷点):
好消息!
小白学视觉知识星球
开始面向外开放啦
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~