python - 如何使用opencv python检测pcb中的缺陷
问题描述
我正在研究我应该检测 PCB 缺陷的项目,我已经尝试过图像减法方法。它检测到 PCB 中缺少组件的缺陷,但即使 PCB 没有缺陷,它也没有给出正确的输出。这意味着即使存在组件,也表明PCB中缺少组件
这是我的代码
g_o_img = cv2.cvtColor(o_img, cv2.COLOR_BGR2GRAY)
g_def_img = cv2.cvtColor(def_img, cv2.COLOR_BGR2GRAY)
score, diff = structural_similarity(g_o_img, g_def_img, full=True)
diff1 = (diff*255).astype("uint8")
cv2.imshow("diff", diff1)
ssim = format(score)
print("SSIM : "+ssim)
l_b = np.array([0])
u_b = np.array([50])
mask = cv2.inRange(diff1, l_b, u_b)
kernel = np.ones((3, 3), np.uint8)
erode = cv2.dilate(mask, kernel)
cv2.imshow("mask", mask)
cv2.imshow("erode", erode)
我已经完成了透视变换,我得到了很好的输出,但是由于我的图像是不同的光照,所以我没有使用图像减法得到正确的输出这是我的代码
img1 = cv2.imread("./pcb_images/orig3.png")
img1 = cv2.resize(img1, (640, 480))
image1 = img1[10:-10,10:-10]
print(image1)
g_o_img = cv2.cvtColor(image1, cv2.COLOR_BGR2LAB) [...,0]
img2 = cv2.imread("./pcb_images/defect4.png")
img2 = cv2.resize(img2, (640, 480))
image2 = img2[10:-10,10:-10]
g_def_img = cv2.cvtColor(image2, cv2.COLOR_BGR2LAB)[...,0]
thresh1 = cv2.threshold(g_o_img, 130, 255, cv2.THRESH_BINARY)[1]
thresh2 = cv2.threshold(g_def_img, 130, 255, cv2.THRESH_BINARY)[1]
res = cv2.bitwise_xor(thresh1, thresh2, mask=None)
解决方案
您必须在背景减法之前进行一些预处理。您必须仅检测 PCB(无背景)并确保视角始终相同。如果透视图不同,请执行一些透视变换以从图像中裁剪 PCB(检查此处)。然后将图像转换为对光和阴影更稳健的颜色空间(检查这里)。之后,您可以进行背景减法,然后进行阈值处理(在此处查看)以获得二值图像。最后,您可以进行形态变换以消除误报(检查此处)并仅保留图像之间的差异。
解决方案
这是上述方法的实现。您可以尝试不同的色彩空间、阈值或形态学内核大小,看看哪一个会给您带来更好的结果。
import cv2
import numpy as np
kernel = np.ones((7,7),np.uint8)
img1 = cv2.imread("orig.png")
img1 = cv2.resize(img1, (640, 480))
image1 = img1[10:-10,10:-10]
img2 = cv2.imread("defect.png")
img2 = cv2.resize(img2, (640, 480))
image2 = img2[10:-10,10:-10]
#Changing color space
g_o_img = cv2.cvtColor(image1, cv2.COLOR_BGR2LAB) [...,0]
g_def_img = cv2.cvtColor(image2, cv2.COLOR_BGR2LAB)[...,0]
#Image subtraction
sub =cv2.subtract(g_o_img, g_def_img)
thresh = cv2.threshold(sub , 130, 255, cv2.THRESH_BINARY)[1]
#Morphological opening
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
#Detecting blobs
params = cv2.SimpleBlobDetector_Params()
params.filterByInertia = False
params.filterByConvexity = False
params.filterByCircularity = False
im=cv2.bitwise_not(opening)
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(im)
#Drawing circle around blobs
im_with_keypoints = cv2.drawKeypoints(img2, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#Display image with circle around defect
cv2.imshow('image',im_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出
推荐阅读
- reactjs - TypeError:加载 svg 时无法读取未定义的属性“tap”
- python - Matplotlib 子图没有按预期工作?
- python - 如何不使用多重继承混淆类变量?
- rust - Rust PyO3 与 cc 的链接失败
- swift - 在 macOS Monterey 上,无法创建快捷操作
- java - Cosmos DB SDK 的连接问题
- angular - Typescript:如何重置从 DI 注入的服务的属性值
- azure-devops - 在一个构建代理上运行所有 azure 管道阶段
- angular - 在ionic 5中单击谷歌地图标记时如何调用模态控制器
- android - 如何在 LocalDateTime 中使用语言环境?