简体   繁体   English

opencv 无法提取图像中的最大轮廓

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

Consider this image:考虑这张图片:

在此处输入图像描述

i want to extract only the number which represent the biggest contour in image but opencv always show the original image and the little contours smaller than number.我只想提取代表图像中最大轮廓的数字,但 opencv 总是显示原始图像和小于数字的小轮廓。 So when i run this function所以当我运行这个 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)

i got this result:我得到了这个结果:

在此处输入图像描述

You are drawing the contours on the same image, so you are getting the larger ROI with two drawn contours.您正在同一图像上绘制轮廓,因此您将获得具有两个绘制轮廓的更大 ROI。

Suggested solution:建议的解决方案:
Draw each contour on a temporary image filled with zeros, and crop the ROI from the temporary image.在填充零的临时图像上绘制每个轮廓,并从临时图像中裁剪 ROI。

  • Create temporary image filled with zeros:创建用零填充的临时图像:

     tmp_im = np.zeros_like(image)
  • Draw a single contour filled with white color, and use it as a mask:绘制一个填充有白色的轮廓,并将其用作蒙版:

     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.
  • Draw green line around the contour (probably not required):在轮廓周围画绿线(可能不需要):

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

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

Complete code sample:完整的代码示例:

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()

Result:结果:

ROI0:投资回报率0:
在此处输入图像描述

ROI1:投资回报率1:
在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM