2

ビデオから車両を数えたい。フレームの差分をとった後、グレースケール画像または一種のバイナリ画像が得られました。フレームの特定の領域で動作するように関心領域を定義しました。関心領域を通過する車両のピクセル値は 0 よりも高く、白いため 40 または 50 よりも高くなります。

私の考えは、特定の時間間隔 (1 ~ 2 秒など) で特定の数のピクセルが白の場合、通過する車両が存在する必要があるため、カウンターをインクリメントするというものです。

私が欲しいのは、1〜2秒後に白いピクセルがまだ来ているかどうかを確認することです。白いピクセルが来ていない場合は、車両が通過し、次の車両が来ることを意味します。このようにして、カウンターをインクリメントする必要があります。

私の頭に浮かんだ 1 つの方法は、ビデオのフレームをカウントし、それを No_of_frames という変数に格納することです。次に、その変数を使用して、経過時間を推定できると思います。変数 No_of_frames の値が 20 より大きい場合、動画のフレーム レートが 25 ~ 30 fps の場合、ほぼ 1 秒が経過したことを意味します。

Windows 7 および OpenCV 2.3.1 で Qt Creator を使用しています。

私のコードは次のようなものです:

             for(int i=0; i<matFrame.rows; i++)
             {
                 for(int j=0;j<matFrame.cols;j++)

                 if (matFrame.at<uchar>(i,j)>100)//values of pixels greater than 100
                                                 //will be considered as white.
                     {
                        whitePixels++;
                     }
                 if ()// here I want to use time. The 'if' statement must be like: 
                 //if (total_no._of_whitepixels>100 && no_white_pixel_came_after 2secs)
                //which means that a vehicle has just passed so increment the counter. 
                    {  
                        counter++;      
                    }
             }

車両を数えるための他のアイデアは、私のものよりも優れており、大歓迎です. 前もって感謝します。

背景のセグメンテーションには、次のアルゴリズムを使用していますが、非常に遅いため、理由がわかりません。コード全体は次のとおりです。

// opencv2/video/background_segm.hpp OPENCV header file must be included.
IplImage*       tmp_frame = NULL;
CvCapture*      cap = NULL;
bool update_bg_model = true;

 Mat element = getStructuringElement( 0, Size( 2,2 ),Point() );
 Mat eroded_frame;
 Mat before_erode;
if( argc > 2 )
    cap = cvCaptureFromCAM(0);

else
//  cap = cvCreateFileCapture( "C:\\4.avi" );
   cap = cvCreateFileCapture( "C:\\traffic2.mp4" );

if( !cap )
{
    printf("can not open camera or video file\n");
    return -1;
}

tmp_frame = cvQueryFrame(cap);
if(!tmp_frame)
{
    printf("can not read data from the video source\n");
    return -1;
}

cvNamedWindow("BackGround", 1);
cvNamedWindow("ForeGround", 1);

CvBGStatModel* bg_model = 0;

for( int fr = 1;tmp_frame; tmp_frame = cvQueryFrame(cap), fr++ )
{
    if(!bg_model)
    {
        //create BG model
        bg_model = cvCreateGaussianBGModel( tmp_frame );
      //  bg_model = cvCreateFGDStatModel( temp );
        continue;
    }

    double t = (double)cvGetTickCount();
    cvUpdateBGStatModel( tmp_frame, bg_model, update_bg_model ? -1 : 0 );
    t = (double)cvGetTickCount() - t;
    printf( "%d. %.1f\n", fr, t/(cvGetTickFrequency()*1000.) );

    before_erode= bg_model->foreground;
    cv::erode((Mat)bg_model->background, (Mat)bg_model->foreground,  element );
    //eroded_frame=bg_model->foreground;
     //frame=(IplImage *)erode_frame.data;

     cvShowImage("BackGround", bg_model->background);
     cvShowImage("ForeGround", bg_model->foreground);
    // cvShowImage("ForeGround", bg_model->foreground);
    char k = cvWaitKey(5);
    if( k == 27 ) break;
    if( k == ' ' )
    {
        update_bg_model = !update_bg_model;
        if(update_bg_model)
            printf("Background update is on\n");
        else
            printf("Background update is off\n");
    }
}
cvReleaseBGStatModel( &bg_model );
cvReleaseCapture(&cap);
return 0;
4

2 に答える 2

2

車両の追跡と計数に関しては、多くの研究が行われてきました。あなたが説明するアプローチは非常に脆弱であるように見え、堅牢または正確である可能性は低いです。主な問題は、空間的な接続性や時間的な関係に関係なく、特定のしきい値を超えるピクセル数を使用することです。

フレーム差分は、対象のオブジェクトが唯一の (または最大の) 移動オブジェクトである場合、移動オブジェクトを背景から分離するのに役立ちます。

実際に必要なのは、最初に関心のあるオブジェクトを識別し、背景からセグメント化し、適応フィルター (カルマン フィルターなど) を使用して経時的に追跡することです。OpenCV ビデオ リファレンスをご覧ください。OpenCV は、バックグラウンド減算とオブジェクト セグメンテーションを提供して、必要なすべての手順を実行します。

OpenCV を読むことをお勧めします - OpenCV を学ぶことは素晴らしい読み物です。また、より一般的なコンピューター ビジョンのアルゴリズムと理論についても、 http://homepages.inf.ed.ac.uk/rbf/CVonline/books.htmに適切なリストがあります。

于 2012-05-11T23:05:23.313 に答える
0

通常、彼らは道路を横切って小さな空気パイプを設置するだけです(空気で満たされた柔らかいパイプ)。シンプルなカウンターに付いています。パイプの上を通過する各車両は、2 つのパルスを生成します (最初に前輪、次に後輪)。カウンターは、指定された時間間隔でパルス数を記録し、2 で除算しておおよその車両数を取得します。

于 2012-08-21T18:20:57.600 に答える