2012-07-12 17 views
6

Jak rozpoznać kontury w obrębie innego konturu? Próbowałem przejść przez wiele tutoriali OpenCV, ale nie byłem w stanie go zidentyfikować. Czy jakiś ekspert może podać prosty kod, aby to wyjaśnić?Jak rozpoznać kontury w obrębie innego konturu za pomocą JavaCV?

To jest mój plik wejściowy

enter image description here

Ta część jest ciemny kontur, że trzeba zidentyfikować.

enter image description here

Proszę być na tyle uprzejmy, aby podzielić się swoimi doświadczeniami ze mną.

+0

Czy możesz podać więcej informacji? Jakie są kryteria wykrywania wypełnionego konturu? – ArtemStorozhuk

Odpowiedz

2

Oto proste podejście w kodzie Pythona. (But as I stated in my comment below, It is not an universal answer applicable everywhere, It is just to show finding contour inside a contour can be done. And if your images are different, then you have to come with some different constraints other than i mentioned below)

To, co robisz po znalezieniu konturów, polega na sprawdzeniu, czy obszar każdego konturu jest mniejszy niż określona wartość (dałem 10000, tylko przypuszczenie), jeśli nie, to większy kontur, unikaj tego. Jeśli jest mniejsza niż podana wartość, może to być nasz kwadrat lub prostokąt obok niego.

Znaleźliśmy więc jego szerokość i wysokość i sprawdzić, czy proporcje są bliskie 1. Jeśli tak, to jest to nasz kwadrat.

import cv2 
import numpy as np 

img = cv2.imread('sofcnt.jpg') 
gray = cv2.imread('sofcnt.jpg',0) 

ret,thresh = cv2.threshold(gray,127,255,1) 

cont,hier = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) 

for cnt in cont: 
    approx = cv2.approxPolyDP(cnt,0.02*cv2.arcLength(cnt,True),True) 
    if cv2.contourArea(cnt) < 10000: 
     x,y,w,h = cv2.boundingRect(cnt) 
     if w/float(h) < 2: 
      cv2.drawContours(img,[cnt],0,255,-1) 


cv2.imshow('a',img) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

Wynik:

enter image description here

+1

Dlaczego myślisz, że potrzebna jest figura podobna do kwadratu wewnątrz jakiegoś ploygonu? Może autor chce znaleźć figurę, która zawiera środek jakiegoś pologona? Dzięki. – ArtemStorozhuk

+1

+1 - Tak, masz rację, wtedy on też musi to określić.Myślę, że chciał zobaczyć, jak zidentyfikować dowolny kontur w obrębie konturu, więc jest to jeden z typów, który to umożliwia. w ten sposób musi znaleźć inne rozwiązanie, i oczywiście nie jest to odpowiedź uniwersalna, tylko dla tego konkretnego problemu. –

+0

Zaktualizowano anwer. –

3

Nie bardzo wygodne z JavaCV, więc oto jak poszedłem na temat rozwiązywania tego problemu w OpenCV i C (starożytny rzeczy):

  1. Znajdź wszystkie kontury na obrazie przy użyciu dwóch pętli (powtórzenie wskaźników).lub cokolwiek tam jest w JavaCV) na tych konturach. Dla każdego konturu w zewnętrznej pętli należy dopasować go do każdego wykrytego innego konturu. . .
  2. Obliczyć obwiednię każdego konturu. Będzie to struktura CvRect.
  3. Przekaż dwa CvRects do funkcji, która oblicza obszar przecięcia (nakładania) między dwa prostokąty.
  4. Jeśli ten obszar jest równy obszarowi mniejszego z dwóch prostokątów, wówczas kontur odpowiadający mniejszemu prostokątowi jest całkowicie zamknięty przez większy.

    Oto kod do znajdowania obszaru przecięcia. Musiało gdzieś dryfować w sieci.

    CvRect intersect(CvRect r1, CvRect r2) { CvRect intersection;

    // find overlapping region 
    intersection.x = (r1.x < r2.x) ? r2.x : r1.x; 
    intersection.y = (r1.y < r2.y) ? r2.y : r1.y; 
    intersection.width = (r1.x + r1.width < r2.x + r2.width) ? 
        r1.x + r1.width : r2.x + r2.width; 
    intersection.width -= intersection.x; 
    intersection.height = (r1.y + r1.height < r2.y + r2.height) ? 
        r1.y + r1.height : r2.y + r2.height; 
    intersection.height -= intersection.y;  
    
    // check for non-overlapping regions 
    if ((intersection.width <= 0) || (intersection.height <= 0)) { 
        intersection = cvRect(0, 0, 0, 0); 
    } 
    
    return intersection; 
    

    }

Powiązane problemy