侵蚀后,重绘轮廓为原始图像

时间:2017-08-01 19:34:12

标签: python opencv numpy contour area

我的功能会根据区域大小或多或少地侵蚀某些轮廓。但是,一旦它们被裁剪,它们将丢失与原始图像对应的适当坐标数据。

如何在保持原始位置的同时将eroded_contours重绘为原始图像?或者是否有更好的方法来使用基于轮廓区域大小的自定义侵蚀?

edged = cv2.Canny(original_image.copy(), 50, 200)
contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

def show_each_contour(original_image):
    for i,c in enumerate(contours):
        area = cv2.contourArea(c)
        if area > 0:
            rect = cv2.boundingRect(c)
            x,y,w,h = rect
            start_row, start_col = int(x), int(y)
            end_row, end_col = int(x+x+w), int(y+y+h)

            cv2.rectangle(original_image, (x,y), (x+w,y+h), (0,0,255), 2)
            cropped = original_image[y:y+h, x:x+w]

            if area < 2000:
                kernel = np.ones((5,5), np.uint8)
                numberOfIterations = area / 200
            else:
                kernel = np.ones((5,5), np.uint8)
                numberOfIterations = 7

            eroded_contours = cv2.erode(cropped.copy(), kernel, iterations = int(numberOfIterations))

        #This won't work correctly because the coordinates are different now
        #cv2.drawContours(original_image, eroded_contours , -1, (0,255,255), 3)

1 个答案:

答案 0 :(得分:1)

如果我理解你的要求,你就非常接近你的目标。

这是我提出的(使用Python 3.6和OpenCV 3.2):

edged = cv2.Canny(input_img.copy(), 50, 200)
_, contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # note that this function returns 3 values

def show_each_contour(original_image):
    margin = 2 # you can set the margin to 0 to better understand its effect
    for i,c in enumerate(contours):
        area = cv2.contourArea(c)
        if area > 0:
            rect = cv2.boundingRect(c)
            x,y,w,h = rect

            cv2.rectangle(original_image, (x-margin,y-margin), (x+w+margin,y+h+margin), (0,0,255), 2)
            cropped = original_image[y-margin:y+h+margin, x-margin:x+w+margin]

            if area < 2000:
                kernel = np.ones((5,5), np.uint8)
                numberOfIterations = area / 200
            else:
                kernel = np.ones((5,5), np.uint8)
                numberOfIterations = 7

            eroded_shape = cv2.erode(cropped.copy(), kernel, iterations = int(numberOfIterations))
            original_image[y-margin:y+h+margin, x-margin:x+w+margin] = eroded_shape # we copy the eroded_shape back into the original_image

除了将侵蚀的形状复制到原始图像的正确位置的最后一行之外,我没有更改任何代码。

结果

input and output images 输入图像在左侧,输出在右侧。

希望这有帮助,请告诉我这是不是你想要的。