opencv-使用光流跟踪车辆

时间:2012-06-23 11:29:57

标签: opencv

我已经实施了光流来跟踪道路上的车辆,但结果却很慢。

我的代码使用函数:

  • cvGoodFeaturesToTrack
  • cvFindCornerSubPix
  • cvCalcOpticalFlowPyrLK

如何快速有效地进行此跟踪?

我的代码是:

#include "highgui.h"
#include "cv.h"
#include "cxcore.h"
#include <iostream>
using namespace std;


const int MAX_CORNERS = 500;

int main()
{
CvCapture* capture=cvCreateFileCapture("E:\cam1.avi");
IplImage* img_A;// = cvLoadImage("image0.png", CV_LOAD_IMAGE_GRAYSCALE);
IplImage* img_B;// = cvLoadImage("image1.png", CV_LOAD_IMAGE_GRAYSCALE);
img_A=cvQueryFrame(capture);

IplImage* imgA = cvCreateImage( cvGetSize(img_A), 8, 1 );
IplImage* imgB = cvCreateImage( cvGetSize(img_A), 8, 1 );
cvNamedWindow( "ImageA", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "ImageB", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "LKpyr_OpticalFlow", CV_WINDOW_AUTOSIZE );

while(1)
{
    int couter=0;
    for(int k=0;k<20;k++)
    {
        img_B=cvQueryFrame(capture);
    }


    //cvCvtColor(imgA,imgA,CV_BGR2GRAY);
    //cvCvtColor(imgB,imgB,CV_BGR2GRAY);
    // Load two images and allocate other structures
    /*IplImage* imgA = cvLoadImage("image0.png", CV_LOAD_IMAGE_GRAYSCALE);
    IplImage* imgB = cvLoadImage("image1.png", CV_LOAD_IMAGE_GRAYSCALE);*/

    CvSize img_sz = cvGetSize( img_A );
    int win_size = 10;



    IplImage* imgC = cvCreateImage( cvGetSize(img_A), 8, 1 );
    cvZero(imgC);
    // Get the features for tracking
    IplImage* eig_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
    IplImage* tmp_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );

    int corner_count = MAX_CORNERS;

    CvPoint2D32f* cornersA = new CvPoint2D32f[ MAX_CORNERS ];


    cvCvtColor(img_A,imgA,CV_BGR2GRAY);

    cvCvtColor(img_B,imgB,CV_BGR2GRAY);


    cvGoodFeaturesToTrack( imgA, eig_image, tmp_image, cornersA, &corner_count ,0.05, 5.0, 0, 3, 0, 0.04 );

    cvFindCornerSubPix( imgA, cornersA, corner_count, cvSize( win_size, win_size ) ,cvSize( -1, -1 ), cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03 ) );

    // Call Lucas Kanade algorithm
    char features_found[ MAX_CORNERS ];
    float feature_errors[ MAX_CORNERS ];

    CvSize pyr_sz = cvSize( imgA->width+8, imgB->height/3 );

    IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
    IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );

    CvPoint2D32f* cornersB = new CvPoint2D32f[ MAX_CORNERS ];

    /*int jk=0;
    for(int i=0;i<imgA->width;i+=10)
    {
        for(int j=0;j<imgA->height;j+=10)
        {
            cornersA[jk].x=i;
            cornersA[jk].y=j;
            ++jk;
        }
    }
  */
    cvCalcOpticalFlowPyrLK( imgA, imgB, pyrA, pyrB, cornersA, cornersB, corner_count,
        cvSize( win_size, win_size ), 5, features_found, feature_errors,
         cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.3 ), 0 );

    // Make an image of the results


    for( int i=0; i < corner_count; i++ ) 
    {
        if( features_found[i]==0|| feature_errors[i]>550 ) 
        {
            //printf("Error is %f/n",feature_errors[i]);
            continue;
        }
        //printf("Got it/n");
        CvPoint p0 = cvPoint( cvRound( cornersA[i].x ), cvRound( cornersA[i].y ) );
        CvPoint p1 = cvPoint( cvRound( cornersB[i].x ), cvRound( cornersB[i].y ) );
        cvLine( imgC, p0, p1, CV_RGB(255,0,0), 2 );
        cout<<p0.x<<" "<<p0.y<<endl;
    }




    cvShowImage( "LKpyr_OpticalFlow", imgC );
    cvShowImage( "ImageA", imgA );
    cvShowImage( "ImageB", imgB );
    //cvCopyImage(imgB,imgA);
    delete[] cornersA;
    delete[] cornersB;
    cvWaitKey(33);
}


return 0;
}

2 个答案:

答案 0 :(得分:12)

我可能会在这里稍微过一点,但我建议你查看OpenTLD。 OpenTLD(aka Predator)是最有效的跟踪算法之一。 Zdenek Kalal在MATLAB中实施了OpenTLD。 George Nebehay提高了效率C++ OpenCV port of OpenTLD

安装非常简单,跟踪非常有效。

OpenTLD使用Median Flow Tracker来跟踪和实现PN学习算法。在此YouTube Video中,Zdenek Kalal展示了OpenTLD的使用。

如果您只想实施中位数流跟踪器,请点击此链接https://github.com/gnebehay/OpenTLD/tree/master/src/mftracker

如果你想在Python中使用它,我已经制作了Median Flow Tracker并且还制作了Python port of OpenTLD。但是python端口效率不高。

答案 1 :(得分:5)

首先要跟踪你必须以某种方式检测它的汽车(例如使用颜色分割/背景减法)。检测到汽车时,您必须使用cvCalcOpticalFlowPyrLK跟踪汽车(跟踪其中的某些点)。我没有找到响应汽车检测的代码。

查看thisthis条款。你的想法应该是一样的。

你的代码也有点不对劲。例如,为什么在主循环中调用cvGoodFeaturesToTrack?你必须调用它一次 - 在循环之前检测要跟踪的好功能。但这也将检测非汽车。

查看默认的OpenCV示例:OpenCV/samples/cpp/lkdemo.cpp