0

J'utilise C++, bibliothèque OpenCV et dans mon logiciel, j'ai estimé le flux optique dans une vidéo. Maintenant, je veux regrouper certains objets en mouvement, par ex. voitures en mouvement. J'ai utilisé un algorithme de flux optique dense (Farneback). Mes premières réflexions jusqu'à présent sont d'utiliser l'algorithme "k means" pour faire le clustering.Segmentation d'image basée sur le flux optique

j'ai pensé à utiliser les résultats du flux optique Farneback pour calculer le déplacement des trames dans chaque direction comme suit:

Par ex :

Soit Dx le déplacement dans la direction x (positive ou négative) et Dy le déplacement dans la direction y (positif ou négatif). Puis je passe le tableau [Dx, Dy] comme une entrée à k signifie avec k = 2 clusters. J'espère que cela donnera une arrière-plan rugueuse/soustraction au premier plan.

Cependant, je suis confronté à des problèmes dans le calcul du displacemet car la sortie de calcOpticalFlowFarneback est un flux InputOutputArray. Dois-je accéder à ce tableau en utilisant une fonction comme celle par exemple? :

findDisplacements(const Mat& flow, int step) { 
const Point2f& Dx,Dy; 
const Point2f& fxy = flow.at<Point2f>(y, x); 
Dx=Point(cvRound(x+fxy.x))-Point(x,y); 
Dy=Point(cvRound(y+fxy.y))-Point(y,x); 
} 
+0

Que avez-vous déjà essayé? – VKatz

+0

J'ai déjà utilisé des kmeans qui fonctionnent je suppose et retourne un tableau bestLabels. Cependant, je n'ai pas réussi à montrer le résultat en tant qu'image. Je travaille aussi sur un autre code utilisant la soustraction d'arrière-plan qui fonctionne également. Devrais-je les combiner? Ou utiliser par exemple la soustraction d'arrière-plan en premier et k signifie plus tard? –

+0

Quel algorithme de flux optique dense avez-vous utilisé? – ChronoTrigger

Répondre

0

Un petit exemple où les vecteurs de mouvement sont utilisés en tant que pour cluster:

cv::Mat img0 = cv::imread("test0.png"); // Image at time t-1 
cv::Mat img1 = cv::imread("test1.png"); // Image at time t 
cv::Mat flow; 
//estimate Optical Flow 
cv::calcOpticalFlowFarneback(img0, img1, flow, 0.5, 3, 21, 20, 5, 1.1); 
std::vector<cv::Point2f> samples(flow.rows * flow.cols); 
// arange sample vector 
int n = 0; 
for(int r = 0; r < flow.rows; r++) { 
    for(int c = 0; c < flow.cols; c++){ 
    samples[n++] = flow.at<cv::Point2f>(r,c); 
}} 
cv::kmeans(samples, ... 
0

Vous pouvez utiliser l'histoire du mouvement.

updateMotionHistory(silh, mhi, timestamp, MHI_DURATION); 
calcMotionGradient(mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3); 
segmentMotion(mhi, segmask, regions, timestamp, MAX_TIME_DELTA);