algorithm - 如何在存在重叠和噪声的情况下从图像中分割主要形状?

标签 algorithm math image-processing graphics computer-vision

我们如何根据引用图像将左图转换为右图?
Reference image

最佳答案


这是一个想法:

  • 加载图像,转换为灰度,以及二值图像的 Otsu 阈值
  • 找到轮廓并用白色填充它
  • 现在我们有一个二值图像,我们可以执行形态学操作。根据您尝试提取的对象,我们可以创建不同的结构内核。对于矩形,我们可以使用 cv2.MORPH_RECT ,对于椭圆,我们可以删除具有更大内核大小的水平部分并使用 cv2.MORPH_ELLIPSE .
  • 然后我们过滤剩余的轮廓并找到矩形和椭圆的旋转边界框

  • 这是过程的可视化




    对于椭圆




    由于您没有指定语言,这里是 Python 的实现
    import cv2
    import numpy as np
    
    # Load image, convert to grayscale, Otsu's threshold for binary image
    image = cv2.imread('1.png')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    
    # Find contours and fill in contour with white
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
        cv2.drawContours(thresh, [c], 0, 255, -1)
    
    # Rectangle ----------------------------------------
    # Morph open to separate rectangular contour
    rectangular_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20, 20))
    rect = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, rectangular_kernel, iterations=4)
    
    # Find contours and draw rotated rectangle onto image
    cnts = cv2.findContours(rect, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    isolated_rect = cv2.minAreaRect(cnts[0])
    box = np.int0(cv2.boxPoints(isolated_rect))
    cv2.drawContours(image, [box], 0, (36,255,12), 3)
    # Rectangle ----------------------------------------
    
    # Ellipse ----------------------------------------
    # Morph open to separate elliptical contour
    horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50,10))
    ellipse = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
    
    # Find contours and filter for ellipse
    cnts = cv2.findContours(ellipse, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    # Filter using contour area, could also use Aspect Ratio or contour approximation
    for c in cnts:
        area = cv2.contourArea(c)
        if area > 20000:
            cv2.drawContours(image, [c], 0, (136,15,212), 3)
    # Ellipse ----------------------------------------
    
    
    # Display
    cv2.imshow('image', image)
    cv2.imshow('thresh', thresh)
    cv2.imshow('rect', rect)
    cv2.imshow('ellipse', ellipse)
    cv2.waitKey()
    

    关于algorithm - 如何在存在重叠和噪声的情况下从图像中分割主要形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69263462/

    相关文章:

    math - 任意精度算术说明

    python - 使用 numpy.polynomial.legendre 时,如何获得将输入转换为 Legendre 多项式参数的函数?

    ios - 值类型和 init 的问题

    matlab - 通过PCA降维后无法生成原始数据

    algorithm - 需要帮助在 MATLAB 中对齐时间序列数据

    ruby - 将所有项目与同一列表中的另一个项目匹配的算法,其中有些有限制

    arrays - 数组中两个随机选择的索引之间的平均距离

    algorithm - 具有最小过冲的子集和变化 : find the subset that sums to >= target,

    c++ - 矩形碰撞

    opencv - 提高低质量扫描图像的 OCR 质量