Problemy ze znalezieniem konturu w obrazie wideo za pomocą C ++ FindContours

Program, nad którym teraz pracuję, toprawie zrobione, ale nie jestem bardzo zadowolony z wyniku. Używając algorytmu Canny'ego, udało mi się uzyskać bardzo wyraźny kontur konturu obiektu, ale program ma problem z rozpoznaniem konturu i narysowaniem konturu czerwoną linią. Program:

void setwindowSettings(){
    namedWindow("Contours", CV_WINDOW_AUTOSIZE);

    createTrackbar("LowerC", "Contours", &lowerC, 255, NULL);
    createTrackbar("UpperC", "Contours", &upperC, 255, NULL);
}

void wait(void)
{
    long t=30000000;
    while(t--);
}

int main(void)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened())  // check if we succeeded
    return -1;

Mat frame,foreground,image;
double pt1, pt2, area;
Rect rect;
int i;

vector<vector<Point> > contours;
vector<vector<Point> > largest_contours;

namedWindow("Capture", CV_WINDOW_AUTOSIZE);
setwindowSettings();

while(1){
    cap >> frame; // get a new frame from camera
    if( frame.empty() )
            break;
    image=frame.clone();

    cvtColor(image,foreground,CV_BGR2GRAY);
    GaussianBlur(foreground,foreground,Size(9,11),0,0);
    Canny(foreground,foreground,lowerC,upperC,3);

    findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);  

    if(contours.empty())
        continue;

    double largest_area = 0;

    for( i= 0; i < contours.size(); i++){  // get the largest contour
        area = fabs(contourArea(contours[i]));
        if(area >= largest_area){
            largest_area = area;
            largest_contours.clear(); 
            largest_contours.push_back(contours[i]);
        }
    }

    if(largest_area>=3000){   // draw the largest contour if exceeded minimum largest area 
        drawContours(image,largest_contours,-1,Scalar(0,0,255),2);
        printf("area = %.f\n",largest_area);
    }

    wait();

    imshow( "Capture",image );
    imshow("Contours",foreground);

    if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

Podsumowanie programu:

Pobierz obrazy z aparatuFiltrowanie szumów (Konwertuj na szary → rozmycie → Canny)Znajdź konturyZnajdź największy kontur i jego obszar na obrazie, czyli obiektNarysuj czerwoną linię wokół obiektu i wydrukuj największy obszarWypłukać i powtórzyć

A wyniki:

Rzadko dostaję to, czego chcę; Wykryto kontur, czerwona linia narysowana (DOBRY):

... i zazwyczaj mam to; Nie wykryto konturu, nie czerwona linia (TEN ZŁY):

Szanse na zdobycieDOBRY są na temat1/20 co nie jest zbyt dobre. Również linia konturu obiektuContours ekran zacznie migać, gdy wokół obiektu pojawi się czerwona linia (patrz obraz DOBRY JEDEN). Do tego pytania używam jednego z moich obiektów (małe czarne kwadratowe pole), ale proszę zauważyć, że głównym celem tego programu do wykrywania obiektów jestdo wykrywania obiektu bez względu na jego kształt lub kolor.

Moje pytania to:

Dlaczego nadal otrzymuję BAD ONES, mimo że kontur jest tak czysty jak dzień?Czy każdy może mieć lepszy pomysł na ulepszenie wykrywania konturu? (tj. lepszy algorytm rozmycia)Jak uniknąć migotania linii konturu, gdy wokół obiektu rysowana jest czerwona linia?

EDYTOWAĆ: Właśnie odkryłem, że mrugnięcie linii konturu nie jest spowodowane czerwoną linią wokół niego (zdrawContourslubline funkcja), ale dzieje się to po wykryciu największego konturufindContours funkcja i obliczana jako największy kontur.

Na pytanie o nie. 3 kliknięciaTUTAJ. WIDEO TUTAJ, KLIKNIJ TO !!!

Z góry dziękuję.

PS: Używam OpenCV 2.4.3 na Ms Visual C ++ 2010 Exp.

questionAnswers(1)

yourAnswerToTheQuestion