2017-08-01 63 views
1

根據區域大小,我有一個或多或少侵蝕某些輪廓的功能。但是,一旦它們被裁剪掉,就會丟失與原始圖像相對應的適當座標數據。在侵蝕後將輪廓重繪爲原始圖像

如何在保持原始位置的同時將我的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

如果我正確地理解了你所問的內容,那麼你已經非常接近你的目標了。

這裏是我想出了(使用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 輸入圖像,並且在右側的輸出。

希望這可以幫助,請告訴我,如果這不是你要找的。