published on in CV

使用计算机视觉技术进行PCB图像连接线检测

上篇 使用计算机视觉技术进行PCB图像焊点检测

引入需要的工具包

我们会使用 matplotlib 进行绘图,并使用 numpy 处理数组相关的数值计算,以及使用 opencv 提供的计算机视觉工具,请确保工作环境可以正确引入并使用它们。

%matplotlib inline

import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np

载入并缩放图像

读取一张图像,将其进行缩放,使最长边对齐image_max_side的值,该值的设置可以根据经验,实际处理的图像和任务来做调整。

image_max_side = 1024
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()

png

引入核心函数

我们会需要使用到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()

png