簡體   English   中英

opencv 無法提取圖像中的最大輪廓

[英]opencv can't extract biggest contour in image

考慮這張圖片:

在此處輸入圖像描述

我只想提取代表圖像中最大輪廓的數字,但 opencv 總是顯示原始圖像和小於數字的小輪廓。 所以當我運行這個 function

def contouTreat(image):
  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
  cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  cnts = cnts[0] if len(cnts) == 2 else cnts[1]
  (cnts, _) = contours.sort_contours(cnts, method="left-to-right")
  cv2.drawContours(image, cnts, -1, (0, 255, 0), 3)
  #cv2_imshow(image)
  ROI_number = 0
  arr=[]
  v=True 
  for c in cnts:
   area = cv2.contourArea(c)
   if area != image.shape[1]*image.shape[0]:
     x,y,w,h = cv2.boundingRect(c)
     #if minc != x:
     
     x,y,w,h = cv2.boundingRect(c)
     #if area < 800 and area > 200:
     #if area < 1620   and h>58 and w <50:
     #if  h>(70*image.shape[1])/100 and w>(60*image.shape[0])/100 :
     if v:
         ROI = image[y:y+h, x:x+w] 
         print(h)
         print(w)
     cv2_imshow(ROI)                 
 return None     
image=cv2.imread("/content/téléchargement (2).png")   
contouTreat(image)

我得到了這個結果:

在此處輸入圖像描述

您正在同一圖像上繪制輪廓,因此您將獲得具有兩個繪制輪廓的更大 ROI。

建議的解決方案:
在填充零的臨時圖像上繪制每個輪廓,並從臨時圖像中裁剪 ROI。

  • 創建用零填充的臨時圖像:

     tmp_im = np.zeros_like(image)
  • 繪制一個填充有白色的輪廓,並將其用作蒙版:

     cv2.drawContours(tmp_im, [c], 0, (255, 255, 255), cv2.FILLED) # Draw white contour on black image tmp_im = cv2.bitwise_and(image, tmp_im) # Apply bitwise with `image` - required in case there are black regions inside the contour.
  • 在輪廓周圍畫綠線(可能不需要):

     cv2.drawContours(tmp_im, [c], -1, (0, 255, 0), 3) # Draw green line around the contour
  • 裁剪投資回報率:

     ROI = tmp_im[y:y + h, x:x + w]

完整的代碼示例:

import numpy as np
import cv2
from imutils import contours

def contouTreat(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    (cnts, _) = contours.sort_contours(cnts, method="left-to-right")
    cv2.drawContours(image, cnts, -1, (0, 255, 0), 3)
    #cv2_imshow(image)
    ROI_number = 0
    arr = []
    v = True 
    for c in cnts:
        area = cv2.contourArea(c)
        if area != image.shape[1] * image.shape[0]:
            x,y,w,h = cv2.boundingRect(c)
               
            if v:
                tmp_im = np.zeros_like(image)
                cv2.drawContours(tmp_im, [c], 0, (255, 255, 255), cv2.FILLED)  # Draw white contour on black image
                tmp_im = cv2.bitwise_and(image, tmp_im)  # Apply bitwise with `image` - required in case there are black regions inside the contour.
                cv2.drawContours(tmp_im, [c], -1, (0, 255, 0), 3)  # Draw green line around the contour

                ROI = tmp_im[y:y + h, x:x + w]

                print(h)
                print(w)

            cv2.imshow('ROI' + str(ROI_number), ROI)
            ROI_number += 1

    return None


image = cv2.imread("telechargement.png")

contouTreat(image)

cv2.waitKey()
cv2.destroyAllWindows()

結果:

投資回報率0:
在此處輸入圖像描述

投資回報率1:
在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM