You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenCV中提取铝线并优化预处理以去除噪声?

铝线连接部位提取的图像预处理优化需求

任务与目标

实习期间需从视觉相机采集的画面中提取铝线连接部位,用于后续机器学习分类;判断导线断裂的逻辑为:提取连接部位并去除背景噪声后,分析焊点灰度值密度,若灰度值曲线下降则判定导线断裂。

当前困境

作为视觉领域新手,已尝试多种边缘检测与分割技术,包括不同滤波器、Grabcut算法、阈值分割、高斯滤波除法,但均无法完全去除噪声:Canny算子的边缘检测结果仍存在噪声,Sobel算子产生的噪声更多,当前效果已是近期能达到的最佳状态。

需求

  1. Canny算子前的图像预处理优化方案
  2. 图像采集相关建议(拍摄场景受空间和流程限制,难以添加相机物理配件,但仍接受相关建议)

当前实现代码

import numpy as np
from PIL import Image
import cv2

blur = 3
canny_low = 15
canny_high = 230
min_area = 0.005
max_area = 0.025
dilate_iter = 10
erode_iter = 10
mask_color = (0.0,0.0,0.0)

image1 = cv2.imread(r"C:/Users/User/Pictures/vlcsnap-2022-11-21-15h59m05s146.png")
image2 = cv2.imread(r"C:/Users/User/Pictures/template2.png")

# function for object extraction from  background
def bgRemoval_seg(source, template):
    global blur, canny_low, canny_high, min_area, max_area, dilate_iter, erode_iter, mask_color
    # change source image and template in gray c
    source = cv2.cvtColor(source, cv2.COLOR_BGR2GRAY)
    template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
    # add gaussian filter for smooth blur
    source = cv2.GaussianBlur(source, (blur,blur), 0)
    template = cv2.GaussianBlur(template, (blur,blur), 0)
    # add bilateral Filter ro remove A LOT of noise ( I tried various values with this filter)
    source = cv2.bilateralFilter(source,7,100,100)
    template = cv2.bilateralFilter(template,7,100,100)
    

   # add adaptive contrast that increases the amount of contours around the object (also increases noise)
    clahe = cv2.createCLAHE(clipLimit=3.7, tileGridSize=(4,4))
    source = clahe.apply(source)
    template = clahe.apply(template)
    
    cv2.imshow("contrast", source)
    cv2.imshow("contrast2", template)
    
    # apply Canny Operator for edge detection
    edges1 = cv2.Canny(source, canny_low, canny_high)
    edges2 = cv2.Canny(template, canny_low, canny_high)
    
    #dilate and erode the image to remove more noise

    edges1 = cv2.dilate(edges1, None)
    edges2 = cv2.dilate(edges2, None)
    
    edges1 = cv2.erode(edges1, None)
    edges2 = cv2.erode(edges2, None)

    
    edges1  = np.array(edges1)
    edges2  = np.array(edges2)
    
    cv2.imshow("edges1", edges1)
    cv2.imshow("edges2", edges2)

    # get the contours and their areas
    contour_info_1 = [(c, cv2.contourArea(c),) for c in cv2.findContours(edges1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]]
    contour_info_2 = [(c, cv2.contourArea(c),) for c in cv2.findContours(edges2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]]
   

    # Get the area of the image as a comparison
    image_area = source.shape[0] * source.shape[1]
        
    # calculate max and min areas in terms of pixels
    max_area = max_area * image_area
    min_area = min_area * image_area

    
    # Set up mask with a matrix of 0's
    mask1 = np.zeros(edges1.shape, dtype = np.uint8)
    # Go through and find relevant contours and apply to mask
    for i in range(0,len(contour_info_1)):   
        # Instead of worrying about all the smaller contours, if the area is smaller than the min, the loop will break
        contour1 = contour_info_1[i]
        if contour1[1] > min_area and contour1[1] < max_area:
            # Add contour to mask
            mask1 = cv2.fillConvexPoly(mask1, contour1[0], (255))
        
    
    # use dilate, erode, and blur to smooth out the mask
    mask = mask1
    mask = cv2.dilate(mask, None, iterations=dilate_iter)
    mask = cv2.erode(mask, None, iterations=erode_iter)
    mask = cv2.GaussianBlur(mask, (blur,blur), 0)
    mask = np.array(mask)
    # Ensures data types match up
    mask_color = np.array(mask_color)
    mask_color = np.reshape(mask_color,[1,3])
    mask = mask.astype('float32') / 255.0           
    source= source.astype('float32') / 255.0
    # Blend the image and the mask
    masked = (mask * source)
    masked = (masked * 255).astype('uint8')

    return masked



while(True):
    
    # Get Region of interest
    x,y,w,h = cv2.selectROI(image1)
    # Recommended values for the crop
    # X: 145 , Y: 292 , W: 1035 , H: 445 
   
    # Crop image and use same crop for template
    imageCrop1 = image1[int(y):int(y+h), int(x):int(x+w)]
    
    print(x,y,w,h)
    
    imageCrop2 = image2[int(y):int(y+h), int(x):int(x+w)]
    
    # Display the resulting frame
    
    cv2.imshow("Foreground Canny ",bgRemoval_seg(imageCrop1, imageCrop2))

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture 

cv2.destroyAllWindows()

相关图像说明

  • 原图:未处理的相机采集画面
  • 滤波后图像:
    • 原图滤波后:经双边滤波和自适应对比度滤波处理后的图像
    • 模板滤波后:模板图经双边滤波和自适应对比度滤波处理后的图像
  • Canny处理后:
    • 原图Canny结果:存在大量阴影及背景噪声的边缘检测结果
    • 模板Canny结果(目标效果):理想的边缘检测效果
  • 最终提取结果:当前能达到的最佳提取效果

内容的提问来源于stack exchange,提问作者MaixmNlandu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:10:29