代码之家  ›  专栏  ›  技术社区  ›  avereux

侵蚀后将轮廓重新绘制为原始图像

  •  1
  • avereux  · 技术社区  · 7 年前

    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 回复  |  直到 7 年前
        1
  •  2
  •   Community leo1    4 年前

    如果我正确地理解了你的要求,那么你已经非常接近你的目标了。

    以下是我的想法(使用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 输入图像在左侧,输出在右侧。

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