上篇 使用计算机视觉技术进行PCB图像焊点检测
引入需要的工具包
我们会使用 matplotlib 进行绘图,并使用 numpy 处理数组相关的数值计算,以及使用 opencv 提供的计算机视觉工具,请确保工作环境可以正确引入并使用它们。
%matplotlib inline
import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np
载入并缩放图像
读取一张图像,将其进行缩放,使最长边对齐image_max_side
的值,该值的设置可以根据经验,实际处理的图像和任务来做调整。
source_image = cv.imread('./samples/10.JPG')
scale = image_max_side / max(source_image.shape[:2])
source_image = cv.resize(source_image, None, fx=scale, fy=scale, interpolation=cv.INTER_AREA)
plt.imshow(source_image)
plt.show()
引入核心函数
我们会需要使用到segmentation_dots
以及segmentation_links
这两个核心功能函数。后者负责连线检测,前者则是对上一节中焊点检测的封装,之所以需要使用到焊点检测,主要是因为连线检测函数需要使用到焊点检测的结果。
from utils import segmentation_dots
from utils import segmentation_links
焊点检测函数如下:
def segmentation_dots(image:np.ndarray, main_channel:int=1) -> np.ndarray:
# convert to single channel
frame = image.copy()
frame[..., main_channel] = 255
gray = cv.cvtColor(frame, cv.COLOR_RGB2GRAY)
# binarization
normal = ((gray - gray.min()) / max(1, (gray.max() - gray.min())) * 255).astype(np.uint8)
blur = cv.GaussianBlur(normal, (7, 7), 0)
ret, thresh = cv.threshold(blur, 127, 255, cv.THRESH_OTSU)
# morphology closing
kernel = np.ones((5, 5), np.uint8)
closing = cv.morphologyEx(thresh, cv.MORPH_CLOSE, kernel, iterations=1)
# redundancy edges
edges = cv.Canny(closing, 100, 200)
edges = cv.morphologyEx(edges, cv.MORPH_CLOSE, kernel, iterations=3)
# composition
final = closing * (edges < 127).astype(np.uint8)
return final
连线检测函数如下,如果觉得不熟悉,可以结合上一节中的内容对比焊点检测函数进行具体的了解:
def segmentation_links(image:np.ndarray, dots_mask:np.ndarray, main_channel:int=1) -> np.ndarray:
# copy main channel
gray = image[..., main_channel].copy()
# binarization
normal = ((gray - gray.min()) / max(1, (gray.max() - gray.min())) * 255).astype(np.uint8)
blur = cv.GaussianBlur(normal, (5, 5), 0)
ret, thresh = cv.threshold(255 - blur, 127, 255, cv.THRESH_OTSU)
# dilate mask of dots
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
dilated = cv.morphologyEx(dots_mask, cv.MORPH_DILATE, kernel, iterations=1)
# composition
final = 255 - thresh * (dilated < 127).astype(np.uint8)
return final
结合焊点检测结果实现连线检测
简单调用两个函数完成检测:
dots_mask = segmentation_dots(source_image)
final = segmentation_links(source_image, dots_mask)
对检测结果进行可视化:
plt.figure(figsize=(15, 10))
plt.subplot(131)
plt.imshow(dots_mask, cmap='gray')
plt.subplot(132)
plt.imshow(final, cmap='gray')
plt.subplot(133)
plt.imshow(source_image, cmap='gray')
plt.show()