首页 > 解决方案 > 如何使用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

标签: pythonopencv

解决方案


您必须在背景减法之前进行一些预处理。您必须仅检测 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()

输出

减法结果 在此处输入图像描述

二进制图像 在此处输入图像描述

缺陷图像 在此处输入图像描述


推荐阅读