首页 > 解决方案 > 从图像中提取已知形状

问题描述

我正在尝试提取这件作品

在此处输入图像描述

由此

在此处输入图像描述

我试图检测形状,没办法,训练一个 haarscascade ......(我没有底片)没办法,......位置可以变化(不是所有的都被插入)并且角度不一样..我不能一张一张地裁剪:-(

有什么建议吗???提前致谢

PS 原始图片在这里https://pasteboard.co/JaTSoJF.png(抱歉> 2Mb)

在处理@ganeshtata 之后,我们得到了

import cv2
import numpy as np
img = cv2.imread('cropsmall.png')
height, width = img.shape[:2]
green_channel = img[:,0:] # Blue channel extraction
res = cv2.fastNlMeansDenoising(green_channel, None, 3, 7, 21) # Non-local means denoising
cv2.imshow('denoised',res)
edges = cv2.Canny(res, 11, 11, 3) # Edge detection
kernel = np.ones((30, 30),np.uint8)
closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # Morphological closing
im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Find all contours in the image

for cnt in contours: # Iterate through all contours
    x, y, w, h = cv2.boundingRect(cnt) # Reject contours whose height is less than half the image height
    if h < height / 2:
        continue
    y = 0 # Assuming that all shapes start from the top of the image
    cv2.rectangle(img, (x, y), \
          (x + w, y + h), (0, 255, 0), 2)
    cv2.imshow('IMG',img)
    cv2.imwrite("test.jpg",img)
    cv2.waitKey(0)

这给了我们

在此处输入图像描述

不错...

标签: pythonimage-processingcv2

解决方案


我使用以下方法来提取问题中指定的模式。

  1. 读取图像并从图像中提取蓝色通道。

    import cv2
    import numpy as np
    img = cv2.imread('image.png') 
    height, width = img.shape[:2]
    blue_channel = img[:,:,0]
    

    蓝色通道 - 在此处输入图像描述

  2. 在蓝色通道图像上应用 OpenCV 的非局部均值去噪算法。这确保了图像中的大部分随机噪声都被平滑了。

    res = cv2.fastNlMeansDenoising(blue_channel, None, 3, 7, 21)
    

    去噪图像 - 在此处输入图像描述

  3. 应用 Canny 边缘检测。

    edges = cv2.Canny(res, 1, 10, 3)
    

    边缘输出 - 在此处输入图像描述

  4. 应用Morpological Closing以尝试关闭图像中的小间隙/孔。

    kernel = np.ones((30, 30),np.uint8)
    closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
    

    应用形态闭合后的图像 - 在此处输入图像描述

  5. 使用cv2.findContours查找图像中的所有轮廓。找到所有轮廓后,我们可以使用cv2.boundingRect确定每个轮廓的边界框。

    im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Find all contours
    
    for cnt in contours: # Iterate through all contours
        x, y, w, h = cv2.boundingRect(cnt) $ Get contour bounding box
        if h < height / 2: # Reject contours whose height is less than half the image height
            continue
        y = 0  # Assuming that all shapes start from the top of the image
        cv2.rectangle(img, (x, y), \
              (x + w, y + h), (0, 255, 0), 2)
    
  6. 最后结果 - 在此处输入图像描述

完整的代码 -

import cv2
import numpy as np
img = cv2.imread('image.png')
height, width = img.shape[:2]
blue_channel = img[:,:,0] # Blue channel extraction
res = cv2.fastNlMeansDenoising(blue_channel, None, 3, 7, 21) # Non-local means denoising
edges = cv2.Canny(res, 1, 10, 3) # Edge detection
kernel = np.ones((30, 30),np.uint8)
closing = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel) # Morphological closing
im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Find all contours in the image

for cnt in contours: # Iterate through all contours
    x, y, w, h = cv2.boundingRect(cnt) # Reject contours whose height is less than half the image height
    if h < height / 2:
        continue
    y = 0 # Assuming that all shapes start from the top of the image
    cv2.rectangle(img, (x, y), \
          (x + w, y + h), (0, 255, 0), 2)

注意 - 此方法适用于您发布的示例图像。它可能/可能不会概括所有图像。


推荐阅读