如何使用OpenCV从图像中提取焊盘区域(条带提取)
焊盘区域提取的优化方案
我来帮你搞定这个焊盘提取的问题~从你当前的输出结果来看,代码只是简单用Otsu阈值+外接矩形裁剪,没精准分离出焊盘区域——毕竟焊盘是多个小区域,直接取外接矩形会把周围多余背景也框进去,而且Otsu全局阈值可能没处理好图像里的灰度差异。
问题根源
你的初始逻辑是对灰度图做全局阈值分割后取外接矩形,但存在两个核心问题:
- 全局阈值(Otsu)无法应对光照不均匀的情况,可能把部分背景误判为前景
- 直接取外接矩形会包含所有前景的最小框,而不是单独提取焊盘区域
改进步骤与代码
我们可以通过预处理降噪+自适应阈值+形态学操作+轮廓掩码的组合来精准提取焊盘:
import cv2 import numpy as np # 读取原始图像 img = cv2.imread('strip.png') grayscale = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 1. 高斯模糊降噪:减少高频噪声,避免阈值分割误判 blurred = cv2.GaussianBlur(grayscale, (5, 5), 0) # 2. 自适应阈值分割:针对局部区域计算阈值,适配光照不均 thresholded = cv2.adaptiveThreshold( blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2 ) # 3. 形态学闭操作:先膨胀再腐蚀,填补焊盘小空洞、去除背景噪声 kernel = np.ones((3, 3), np.uint8) cleaned_mask = cv2.morphologyEx(thresholded, cv2.MORPH_CLOSE, kernel) # 4. 提取焊盘轮廓并生成掩码 contours, _ = cv2.findContours(cleaned_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) pad_mask = np.zeros_like(grayscale) cv2.drawContours(pad_mask, contours, -1, 255, thickness=cv2.FILLED) # 5. 提取焊盘区域并裁剪到最小范围 pad_region = cv2.bitwise_and(img, img, mask=pad_mask) x, y, w, h = cv2.boundingRect(pad_mask) cropped_pads = pad_region[y:y+h, x:x+w] # 保存结果 cv2.imwrite("extracted_pads.png", cropped_pads)
步骤解释
- 高斯模糊:平滑图像,过滤掉可能干扰阈值分割的细小噪声点
- 自适应阈值:相比全局Otsu阈值,它会根据每个像素周围11x11的区域计算阈值,能更好区分焊盘和不均匀的背景
- 形态学闭操作:用3x3的核先膨胀(填补焊盘内部小缝隙)再腐蚀(去除背景小噪点),让焊盘区域更完整
- 轮廓掩码:通过轮廓找到所有焊盘的位置,用掩码精准保留焊盘区域,最后裁剪到包含所有焊盘的最小矩形,得到你想要的结果
内容的提问来源于stack exchange,提问作者T. Swiz
相关产品推荐
相关产品推荐

