2012-09-08 8 views
8

Próbuję utworzyć proste śledzenie blobów przy użyciu OpenCV. Wykryłem blobs za pomocą findcontours. Chciałbym nadać tym obiektom stałą identyfikację.Algorytm śledzenia blobów

Zbierałem listę plamek w poprzedniej ramce i bieżącej ramce. Potem wziąłem odległość między każdą kroplą w poprzedniej klatce a bieżącą ramką. Chciałbym wiedzieć, co jeszcze jest potrzebne, aby śledzić plamki i dać im identyfikator. Po prostu przejąłem odległość między poprzednimi i bieżącymi blokami ramki, ale jak mogę przypisać obiektom blob spójny identyfikator, wykorzystując zmierzoną odległość między obiektami typu blob?

+0

Czy możesz zilustrować swoje pytanie, proszę? – bokan

+1

zmodyfikował pytanie –

Odpowiedz

6

W pierwszej ramce można przypisać id w dowolny sposób, 1 dla pierwszego znalezienia, 2 dla drugiego ... lub po prostu dać im identyfikator zgodnie z ich pozycją w kolekcji.

Następnie w następnej klatce będziesz musiał użyć najlepszego dopasowania. Znajdź obiekty typu blob, oblicz wszystkie odległości między bieżącymi obiektami blob i wszystkimi obiektami blobu z poprzedniego obrazu i przypisz każdy poprzedni identyfikator do najbliższego obiektu typu blob. Bloby, które właśnie wejdą na pole otrzymają nowe identyfikatory.

Teraz masz dwie ramki, możesz przewidzieć ruch dla następnej. Wystarczy obliczyć deltaX i deltaY między poprzednią a bieżącą pozycją obiektu blob. Możesz użyć tych informacji do odgadnięcia przyszłej pozycji. Dopasuj się do tej przyszłej pozycji.

Powinno to zadziałać, jeśli nie ma wielu nakładających się obiektów typu BLOB, a jeśli ruch nie jest zbyt szybki i nieregularny między poszczególnymi ramkami.

Możliwe jest dokładniejsze używanie systemu punktowania za pomocą kilku zdjęć:
Zdobądź pozycje dla pierwszych 3 lub 5 zdjęć. Dla każdej kropli pierwszej klatki wyszukaj najbliższą klatkę 2, oblicz prędkość (deltaX deltaY), wyszukaj najbliższą przewidywaną pozycję dla klatki 3, 4, 5 ... Zsumuj wszystkie odległości między przewidywaną pozycją a najbliższą kroplą, być wynikiem. Zrób to samo, używając drugiej najbliższej na ramie 2 (będzie szukać w innym kierunku). Im niższy wynik, tym najprawdopodobniej jest to dobry blob.

Jeśli masz dużo obiektów typu blob, powinieneś użyć przyspieszacza do poczwórnego programu quadtree. Porównaj kwadrat odległości; pozwoli uniknąć wielu obliczeń sqrt.

Ważne jest, aby wiedzieć, w jaki sposób Twoja kropla porusza się typowo w celu strojenia algotrmatu.

+0

Dzięki, proszę podać mi więcej wyjaśnień na podstawie przykładów i obliczeń lub zdjęć? Byłbym bardzo szczęśliwy mogąc zrozumieć ten proces. Możesz też pokazać mi odniesienie do tego –

+0

@MoazELdeen Edytowałem odpowiedź – bokan

3

Oto przykładowy kod OpenCV śledzenia blob:

#include "stdafx.h" 

#include <opencv2\opencv.hpp> 

IplImage* GetThresholdedImage(IplImage* img) 
{ 
    // Convert the image into an HSV image 
    IplImage* imgHSV = cvCreateImage(cvGetSize(img), 8, 3); 
    cvCvtColor(img, imgHSV, CV_BGR2HSV); 

    IplImage* imgThreshed = cvCreateImage(cvGetSize(img), 8, 1); 

    // Values 20,100,100 to 30,255,255 working perfect for yellow at around 6pm 
    cvInRangeS(imgHSV, cvScalar(112, 100, 100), cvScalar(124, 255, 255), imgThreshed); 

    cvReleaseImage(&imgHSV); 

    return imgThreshed; 
} 

int main() 
{ 
    // Initialize capturing live feed from the camera 
    CvCapture* capture = 0; 
    capture = cvCaptureFromCAM(0); 

    // Couldn't get a device? Throw an error and quit 
    if(!capture) 
    { 
     printf("Could not initialize capturing...\n"); 
     return -1; 
    } 

    // The two windows we'll be using 
    cvNamedWindow("video"); 
    cvNamedWindow("thresh"); 

    // This image holds the "scribble" data... 
    // the tracked positions of the ball 
    IplImage* imgScribble = NULL; 

    // An infinite loop 
    while(true) 
    { 
     // Will hold a frame captured from the camera 
     IplImage* frame = 0; 
     frame = cvQueryFrame(capture); 

     // If we couldn't grab a frame... quit 
     if(!frame) 
      break; 

     // If this is the first frame, we need to initialize it 
     if(imgScribble == NULL) 
     { 
      imgScribble = cvCreateImage(cvGetSize(frame), 8, 3); 
     } 

     // Holds the yellow thresholded image (yellow = white, rest = black) 
     IplImage* imgYellowThresh = GetThresholdedImage(frame); 

     // Calculate the moments to estimate the position of the ball 
     CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments)); 
     cvMoments(imgYellowThresh, moments, 1); 

     // The actual moment values 
     double moment10 = cvGetSpatialMoment(moments, 1, 0); 
     double moment01 = cvGetSpatialMoment(moments, 0, 1); 
     double area = cvGetCentralMoment(moments, 0, 0); 

     // Holding the last and current ball positions 
     static int posX = 0; 
     static int posY = 0; 

     int lastX = posX; 
     int lastY = posY; 

     posX = moment10/area; 
     posY = moment01/area; 

     // Print it out for debugging purposes 
     printf("position (%d,%d)\n", posX, posY); 

     // We want to draw a line only if its a valid position 
     if(lastX>0 && lastY>0 && posX>0 && posY>0) 
     { 
      // Draw a yellow line from the previous point to the current point 
      cvLine(imgScribble, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,255,255), 5); 
     } 

     // Add the scribbling image and the frame... and we get a combination of the two 
     cvAdd(frame, imgScribble, frame); 
     cvShowImage("thresh", imgYellowThresh); 
     cvShowImage("video", frame); 

     // Wait for a keypress 
     int c = cvWaitKey(10); 
     if(c!=-1) 
     { 
      // If pressed, break out of the loop 
      break; 
     } 

     // Release the thresholded image... we need no memory leaks.. please 
     cvReleaseImage(&imgYellowThresh); 

     delete moments; 
    } 

    // We're done using the camera. Other applications can now use it 
    cvReleaseCapture(&capture); 
    return 0; 
} 
1

u mogą korzystać cvblobslib bibliotekę do wykrywania kropelka ...

  1. jeśli ruch blob inter-frame jest mniejsza niż między blob odległość .., która jest przesunięcie blob jest mniejsza niż odległość między blob następnie możesz utworzyć listę i nadal dodawać blob w każdej bieżącej klatce, które mieszczą się w sąsiedztwie plamy w poprzedniej klatce ...
  2. jeśli yo ur-bloby mają pewne stałe cechy, takie jak eliptyczność ... współczynnik proporcji (po dopasowaniu do niego ramki ograniczającej) możesz grupować obiekty z tymi funkcjami na listę ..