2

人間のモーショントラッキングの実装を探しています。また、差分分析とlukaskanade光学法を使用して複数のビデオフレームから抽出された複数の移動物体検出についても説明しました。

科学論文を見つけ、連続モーショントラッキングのために連結成分をフィルタリングする連結成分を使用する必要があることがわかりましたが、このプロセスの進め方がわかりません。必要なのは、スケルトン化の軌跡と人間の歩行運動の座標だけです。

私はOpencvとC++で作業していますが、私の場合、オブジェクト検出のためのopencvのドキュメントでは不十分です。私は医学のバックグラウンドを持っており、これは小児科医のプロジェクトの一部である必要があります。

私はこのコードモーション検出を見つけて実行しようとしました(モーションを検出して追跡するかどうかはまだわかりません)。ただし、これらのエラーが返され、エラーが些細なものであり、他のコメントでこのコードを実行できることに戸惑っています。しかし、私はこれらのエラーを軽減することも、それらが発生する理由を理解することもできません。OpenCv2.3を使用していますが、次のエラーが発生します

  1. サースファイルstdafx.hを開くことができません
  2. 警告C4996:'fopen':この関数または変数は安全でない可能性があります。代わりにfopen_sの使用を検討してください。非推奨を無効にするには、_CRT_SECURE_NO_WARNINGSを使用します。詳細については、オンラインヘルプを参照してください。
  3. エラーC2086:'CvSize imgSize':再定義
  4. エラーC2065:'temp':宣言されていない識別子
  5. エラーC4430:型指定子がありません-intと見なされます。注:C++はdefault-intをサポートしていません
    • エラーC2365:'cvReleaseImage':再定義; 以前の定義は「function」1>c:\ opencv2.3 \ opencv \ build \ include \ opencv2 \ core \ core_c.h(87):「cvReleaseImage」の宣言を参照
  6. エラーC2065:'差異':宣言されていない識別子
  7. エラーC4430:型指定子がありません-intと見なされます。注:C++はdefault-intをサポートしていません
  8. エラーC2365:'cvReleaseImage':再定義; 以前の定義は「function」1>c:\ opencv2.3 \ opencv \ build \ include \ opencv2 \ core \ core_c.h(87):「cvReleaseImage」の宣言を参照
  9. エラーC2065:'greyImage':宣言されていない識別子
  10. エラーC4430:型指定子がありません-intと見なされます。注:C++はdefault-intをサポートしていません
  11. エラーC2365:'cvReleaseImage':再定義; 以前の定義は「関数」でした
  12. \ opencv2.3 \ opencv \ build \ include \ opencv2 \ core \ core_c.h(87):「cvReleaseImage」エラーの宣言を参照C2065:「movingAverage」:宣言されていない識別子-エラーC4430:型指定子がありません-intと見なされます。注:C++はdefault-int-errorをサポートしていません。C2365:'cvReleaseImage':redefinition; 以前の定義は「function」-1>c:\ opencv2.3 \ opencv \ build \ include \ opencv2 \ core \ core_c.h(87):「cvReleaseImage」の宣言を参照-エラーC4430:型指定子がありません-intと見なされます。注:C++はdefault-int-errorをサポートしていません。C2365:'cvDestroyWindow':redefinition; 以前の定義は「関数」でした
  13. c:\ opencv2.3 \ opencv \ build \ include \ opencv2 \ highgui \ highgui_c.h(136):「cvDestroyWindow」の宣言を参照
  14. エラーC2440:'初期化中':'const char[10]'から'int'に変換できません-1>この変換が可能なコンテキストはありません-エラーC2065:'入力':宣言されていない識別子-エラーC4430:型がありません指定子-intが想定されます。注:C++はdefault-intをサポートしていません
  15. エラーC2365:'cvReleaseCapture':再定義; 以前の定義は「function」-1>c:\ opencv2.3 \ opencv \ build \ include \ opencv2 \ highgui \ highgui_c.h(311):「cvReleaseCapture」の宣言を参照-エラーC2065:「outputMovie」:宣言されていない識別子
  16. エラーC4430:型指定子がありません-intと見なされます。注:C++はdefault-int-errorをサポートしていません。C2365:'cvReleaseVideoWriter':redefinition; 以前の定義は「function」-1c:\ opencv2.3 \ opencv \ build \ include \ opencv2 \ highgui \ highgui_c.h(436):「cvReleaseVideoWriter」の宣言を参照-エラーC2059:構文エラー:「return」== ========ビルド:0成功、1失敗、0最新、0スキップ==========

コード

// MotionDetection.cpp : Defines the entry point for the console application.
//


// Contourold.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"

#include "iostream"
#include "stdlib.h"

// OpenCV includes.
#include "cv.h"
#include "highgui.h"
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")

using namespace std;

int main(int argc, char* argv[])
{

//Create a new window.
cvNamedWindow("My Window", CV_WINDOW_AUTOSIZE);

//Create a new movie capture object.
CvCapture *input;

//Assign the movie to capture.
//inputMovie = cvCaptureFromAVI("vinoth.avi");

char *fileName = "E:\\highway.avi";
//char *fileName = "D:\\Profile\\AVI\\cardriving.wmv";
input = cvCaptureFromFile(fileName);
//if (!input)

//cout << "Can't open file" << fileName < ;



//Size of the image.
CvSize imgSize;
IplImage* frame = cvQueryFrame(input);
CvSize imgSize = cvGetSize(frame);

//Images to use in the program.
IplImage* greyImage = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);
IplImage* colourImage;
IplImage* movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
IplImage* difference;
IplImage* temp;
IplImage* motionHistory = cvCreateImage( imgSize, IPL_DEPTH_8U, 3);

//Rectangle to use to put around the people.
CvRect bndRect = cvRect(0,0,0,0);

//Points for the edges of the rectangle.
CvPoint pt1, pt2;

//Create a font object.
CvFont font;


//Create video to output to.
char* outFilename = argc==2 ? argv[1] : "E:\\outputMovie.avi";
CvVideoWriter* outputMovie = cvCreateVideoWriter(outFilename,
CV_FOURCC('F', 'L', 'V', 'I'), 29.97, cvSize(720, 576));

//Capture the movie frame by frame.
int prevX = 0;
int numPeople = 0;

//Buffer to save the number of people when converting the integer
//to a string.
char wow[65];

//The midpoint X position of the rectangle surrounding the moving objects.
int avgX = 0;

//Indicates whether this is the first time in the loop of frames.
bool first = true;

//Indicates the contour which was closest to the left boundary before the object
//entered the region between the buildings.
int closestToLeft = 0;
//Same as above, but for the right.
int closestToRight = 320;

//Keep processing frames...
for(;;)
{
//Get a frame from the input video.
colourImage = cvQueryFrame(input);

//If there are no more frames, jump out of the for.
if( !colourImage )
{
break;
}

//If this is the first time, initialize the images.
if(first)
{
difference = cvCloneImage(colourImage);
temp = cvCloneImage(colourImage);
cvConvertScale(colourImage, movingAverage, 1.0, 0.0);
first = false;
}
//else, make a running average of the motion.
else
{
cvRunningAvg(colourImage, movingAverage, 0.020, NULL);
}

//Convert the scale of the moving average.
cvConvertScale(movingAverage,temp, 1.0, 0.0);

//Minus the current frame from the moving average.
cvAbsDiff(colourImage,temp,difference);

//Convert the image to grayscale.
cvCvtColor(difference,greyImage,CV_RGB2GRAY);

//Convert the image to black and white.
cvThreshold(greyImage, greyImage, 70, 255, CV_THRESH_BINARY);

//Dilate and erode to get people blobs
cvDilate(greyImage, greyImage, 0, 18);
cvErode(greyImage, greyImage, 0, 10);

//Find the contours of the moving images in the frame.
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvFindContours( greyImage, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

//Process each moving contour in the current frame...
for( ; contour != 0; contour = contour->h_next )
{
//Get a bounding rectangle around the moving object.
bndRect = cvBoundingRect(contour, 0);

pt1.x = bndRect.x;
pt1.y = bndRect.y;
pt2.x = bndRect.x + bndRect.width;
pt2.y = bndRect.y + bndRect.height;

//Get an average X position of the moving contour.
avgX = (pt1.x + pt2.x) / 2;

//If the contour is within the edges of the building...
if(avgX > 90 && avgX < 250)
{
//If the the previous contour was within 2 of the left boundary...
if(closestToLeft >= 88 && closestToLeft <= 90)
{
//If the current X position is greater than the previous...
if(avgX > prevX)
{
//Increase the number of people.
numPeople++;

//Reset the closest object to the left indicator.
closestToLeft = 0;
}
}
//else if the previous contour was within 2 of the right boundary...
else if(closestToRight >= 250 && closestToRight <= 252)
{
//If the current X position is less than the previous...
if(avgX < prevX)
{
//Increase the number of people.
numPeople++;

//Reset the closest object to the right counter.
closestToRight = 320;
}
}

//Draw the bounding rectangle around the moving object.
cvRectangle(colourImage, pt1, pt2, CV_RGB(255,0,0), 1);
}

//If the current object is closer to the left boundary but still not across
//it, then change the closest to the left counter to this value.
if(avgX > closestToLeft && avgX <= 90)
{
closestToLeft = avgX;
}

//If the current object is closer to the right boundary but still not across
//it, then change the closest to the right counter to this value.
if(avgX < closestToRight && avgX >= 250)
{
closestToRight = avgX;
}

//Save the current X value to use as the previous in the next iteration.
prevX = avgX;
}
//Save the current X value to use as the previous in the next iteration.
prevX = avgX;
}


//Write the number of people counted at the top of the output frame.
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.8, 0.8, 0, 2);
cvPutText(colourImage, _itoa(numPeople, wow, 10), cvPoint(60, 200), &font, cvScalar(0, 0, 300));

//Show the frame.
cvShowImage("My Window", colourImage);

//Wait for the user to see it.
cvWaitKey(10);

//Write the frame to the output movie.
cvWriteFrame(outputMovie, colourImage);
}

// Destroy the image, movies, and window.
cvReleaseImage(&temp);
cvReleaseImage(&difference);
cvReleaseImage(&greyImage);
cvReleaseImage(&movingAverage);
cvDestroyWindow("My Window");

cvReleaseCapture(&input);
cvReleaseVideoWriter(&outputMovie);


return 0;

}
  • エラーや問題の解決にご協力ください。
  • おそらくスケルトン化法によって軌道の座標を返すモーション(人間)追跡の方法。
4

2 に答える 2

5

コードをコンパイルしようとすると、3 ~ 4 個のバグを見つけることができます。

  1. 必要ありません#include "stdafx.h"
  2. imgSize使用する行で再宣言しますcvGetSize(frame)
  3. 最後の括弧が一致しません。
  4. _itoa()コードで宣言されていないため、関数を確認できます。
于 2013-01-14T01:49:35.533 に答える
4

1.)Webサイトからコードを直接コピーしたと思います(間違っている場合は訂正してください)。ただし、OpenCV 2.3を使用しているため、ほとんどのAPIは異なるモジュールに含まれています。次のインクルードが必要です...

#include <opencv/core/core.hpp>
#include <opencv/highgui/highgui.hpp>
#include <opencv/imgproc/imgproc.hpp>

およびそれぞれのライブラリ。

2.)連結成分のフィルタリングには、cvblobライブラリを使用できます。OpenCVによって提供された古いBlobライブラリはVC6を使用して構築されたと思うので、必要な場合がありますstdafx.h

3.)構文と再宣言エラーについて、コードをゆっくりと調べます。

編集されたコード

#include <iostream>
#include "stdlib.h"


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "cv.h"
#include "highgui.h"

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
    cvNamedWindow("My Window", CV_WINDOW_AUTOSIZE);
    CvCapture *input;

    //char *fileName = "E:\\highway.avi";
    input = cvCaptureFromCAM(0);

    //input = cvCaptureFromFile(fileName);

    CvSize imgSize;
    IplImage* frame = cvQueryFrame(input);
    imgSize = cvGetSize(frame);

    IplImage* greyImage = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);
    IplImage* colourImage;
    IplImage* movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
    IplImage* difference;
    IplImage* temp;
    IplImage* motionHistory = cvCreateImage( imgSize, IPL_DEPTH_8U, 3);

    CvRect bndRect = cvRect(0,0,0,0);

    CvPoint pt1, pt2;

    CvFont font;


    char* outFilename = argc==2 ? argv[1] : "E:\\outputMovie.avi";
    CvVideoWriter* outputMovie = cvCreateVideoWriter(outFilename,
    CV_FOURCC('F', 'L', 'V', 'I'), 29.97, cvSize(720, 576));

    int prevX = 0;
    int numPeople = 0;

    char wow[65];

    int avgX = 0;

    bool first = true;

    int closestToLeft = 0;
    int closestToRight = 320;

    for(;;)
        {
        colourImage = cvQueryFrame(input);

        if( !colourImage )
            {
            break;
            }
        if(first)
            {
            difference = cvCloneImage(colourImage);
            temp = cvCloneImage(colourImage);
            cvConvertScale(colourImage, movingAverage, 1.0, 0.0);
            first = false;
            }
        else

            {
            cvRunningAvg(colourImage, movingAverage, 0.020, NULL);
            }

        cvConvertScale(movingAverage,temp, 1.0, 0.0);

        cvAbsDiff(colourImage,temp,difference);

        cvCvtColor(difference,greyImage,CV_RGB2GRAY);

        cvThreshold(greyImage, greyImage, 70, 255, CV_THRESH_BINARY);

        cvDilate(greyImage, greyImage, 0, 18);
        cvErode(greyImage, greyImage, 0, 10);

        CvMemStorage* storage = cvCreateMemStorage(0);
        CvSeq* contour = 0;

        cvFindContours( greyImage, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );


        for( ; contour != 0; contour = contour->h_next )
        {
            bndRect = cvBoundingRect(contour, 0);
            pt1.x = bndRect.x;
            pt1.y = bndRect.y;
            pt2.x = bndRect.x + bndRect.width;
            pt2.y = bndRect.y + bndRect.height;

            avgX = (pt1.x + pt2.x) / 2;

        if(avgX > 90 && avgX < 250)
        {
            if(closestToLeft >= 88 && closestToLeft <= 90)
                {
                if(avgX > prevX)
                    {
                    numPeople++;
                    closestToLeft = 0;
                    }
                }
            else if(closestToRight >= 250 && closestToRight <= 252)
                {
                if(avgX < prevX)
                    {
                    numPeople++;
                    closestToRight = 320;
                    }
                }
            cvRectangle(colourImage, pt1, pt2, CV_RGB(255,0,0), 1);
         }

        if(avgX > closestToLeft && avgX <= 90)
            {
            closestToLeft = avgX;
            }

        if(avgX < closestToRight && avgX >= 250)
            {
            closestToRight = avgX;
            }

        prevX = avgX;
        prevX = avgX;

        }

        cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.8, 0.8, 0, 2);
        cvPutText(colourImage, _itoa(numPeople, wow, 10), cvPoint(60, 200), &font, cvScalar(0, 0, 300));
        cvShowImage("My Window", colourImage);

        cvWaitKey(10);
        cvWriteFrame(outputMovie, colourImage);

    }


    cvReleaseImage(&temp);
    cvReleaseImage(&difference);
    cvReleaseImage(&greyImage);
    cvReleaseImage(&movingAverage);
    cvDestroyWindow("My Window");

    cvReleaseCapture(&input);
    cvReleaseVideoWriter(&outputMovie);


return 0;

}

少なくとも正しくコンパイルされています...実行時エラーが発生しています...現在追跡するデバッガーがありません...試してみてください...私も試してみています。

于 2013-01-14T02:29:04.070 に答える