Как найти самый большой контур моего изображения?

#python #python-3.x #numpy #opencv #image-processing

#python #python-3.x #numpy #opencv #обработка изображений

Вопрос:

Я искал метод, который может выполнять поиск по самому большому контуру изображения. Я работал в программе, которая может обнаруживать руку, но на изображениях иногда появляются большие двоичные объекты или обнаруживается какой-то маленький объект. Я попробовал некоторые методы, такие как поиск с помощью cv2.contourArea и cv2.arcLength() , но это не сработало в моем коде.

это мой код:

 import cv2
import numpy as np
import xlsxwriter

def SkinColorUpper (Hue,mult1,mult2):
    upper = [Hue,mult1*255,mult2*255]
    upper = np.array(upper)
    return upper

def SkinColorLower (Hue,mult1,mult2):
    lower = [Hue,mult1*255,mult2*255]
    lower = np.array(lower)
    return lower

direc = ('Fotos/A/1.jpg')
img = cv2.imread(direc,1)
# cv2.imshow("Imagen",img)
# cv2.waitKey(0)
heigth, width = img.shape[:2]
#print (img.shape)

start_row,start_col = int(0),int(0)
end_row, end_col = int(heigth), int(width*.3)
img = img[start_row:end_row,start_col:end_col]

hls = cv2.cvtColor(img,cv2.COLOR_BGR2HLS)

mask = cv2.inRange(hls,SkinColorLower(0,0.2,0),SkinColorUpper(27,0.72,0.75))
#mask = cv2.inRange(hls,np.array([0,49,61]),np.array([20,255,127]))

blur = cv2.medianBlur(mask,5)

ret,edges = cv2.threshold(blur,0,255,cv2.THRESH_BINARY   cv2.THRESH_OTSU)
#edges = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_CHRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 2)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
edges= cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)

contours, hierarchy = cv2.findContours(edges.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
draw = cv2.drawContours(img,contours,-1,(255,0,0),3)
#print(contours)
cv2.imshow("mask",img)
cv2.waitKey(0)

for component in zip(contours,hierarchy):
    current_contour = component[0]
    x,y,w,h = cv2.boundingRect(current_contour)
    p = cv2.arcLength(current_contour,True)
    epsilon = p*0.015
    approx = cv2.approxPolyDP(current_contour,epsilon,True)
    lados = len(approx)
    empty = np.zeros((h,w),np.uint8)
    cv2.rectangle(img,(x,y),(x w,y h),(255,0,0),1)
    roi = edges[y:y h,x:x w]
    empty[0:h,0:w]=roi
    edges=empty
    cv2.imshow("Edges",edges)
    cv2.waitKey(0)  
    img_resize = cv2.resize(edges,(150,150),interpolation=cv2.INTER_AREA)
    ret, edges_res = cv2.threshold(img_resize,0,255,cv2.THRESH_BINARY   cv2.THRESH_OTSU)
    cv2.imshow("img_resize",img_resize)
    cv2.waitKey(0)
    contours_2,hierarchy_2 = cv2.findContours(edges_res.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    
    for component_2 in zip(contours_2,hierarchy_2):
        currentContour =  component_2[0]
        x,y,w,h = cv2.boundingRect(currentContour)
        M = cv2.moments(currentContour)
        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])
        A = cv2.contourArea(currentContour)
        p = cv2.arcLength(currentContour,True)
        aP=A/float(p*p)
        #print(M['m10'],M['m01'],M['m00'],cx,cy,A,p,aP)
        Hu = cv2.HuMoments(M)
        # print(Hu)
cv2.destroyAllWindows()
  

Итак, я хочу знать, как я могу найти самый большой контур, чтобы избежать этих двоичных объектов

Комментарии:

1. если нужный контур извлечен правильно, вы можете.используйте, например, contourrea или boundingRect или minarearrect (в зависимости от вашего определения «самого большого»). Если контур не извлекается правильно, вам понадобятся более продвинутые методы, чем пороговое значение и морфология… Может быть очень сложной проблемой для решения.

2. Спасибо! Я решил проблему с помощью друзей.