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 (zdrawContours
lubline
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.