Thursday 11 April 2019

c++ - Error in opencv code for motion detection



I am looking for implementation of human motion tracking, also discussed about in multiple moving object detection extracted from several video frames using differential analysis and lukas kanade optical method.



I found scientific papers and found that we have to use connected components filtering connected components for continuous motion tracking, but I do not understand how to go about this process. All I need are the skeletonization trajectory and the coordinates of human gait motion.



I am working in Opencv and C++, but the documentation in opencv for object detection won't suffice in my case. I am from medical background and need this is a part of a paediatrician project.



I found this code motion detection and was trying to execute it (don not know if it detects and tracks motion, yet). However, it returns these errors and I am perplexed for the errors are trivial and other comments mention that they are able to run this code. But I cannot mitigate these erros nor can I understand the reason for them occuring. I am using OpenCv2.3 and following are the errors





  1. Cannot open surce file stdafx.h

  2. warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

  3. error C2086: 'CvSize imgSize' : redefinition

  4. error C2065: 'temp' : undeclared identifier

  5. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int


    • error C2365: 'cvReleaseImage' : redefinition; previous definition was 'function'
      1> c:\opencv2.3\opencv\build\include\opencv2\core\core_c.h(87) : see declaration of 'cvReleaseImage'



  6. error C2065: 'difference' : undeclared identifier

  7. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

  8. error C2365: 'cvReleaseImage' : redefinition; previous definition was 'function'
    1> c:\opencv2.3\opencv\build\include\opencv2\core\core_c.h(87) : see declaration of 'cvReleaseImage'

  9. error C2065: 'greyImage' : undeclared identifier

  10. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

  11. error C2365: 'cvReleaseImage' : redefinition; previous definition was 'function'

  12. \opencv2.3\opencv\build\include\opencv2\core\core_c.h(87) : see declaration of 'cvReleaseImage'
    error C2065: 'movingAverage' : undeclared identifier

    -error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    -error C2365: 'cvReleaseImage' : redefinition; previous definition was 'function'
    -1> c:\opencv2.3\opencv\build\include\opencv2\core\core_c.h(87) : see declaration of 'cvReleaseImage'
    -error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    -error C2365: 'cvDestroyWindow' : redefinition; previous definition was 'function'

  13. c:\opencv2.3\opencv\build\include\opencv2\highgui\highgui_c.h(136) : see declaration of 'cvDestroyWindow'

  14. error C2440: 'initializing' : cannot convert from 'const char [10]' to 'int'
    -1> There is no context in which this conversion is possible
    -error C2065: 'input' : undeclared identifier
    -error C4430: missing type specifier - int assumed. Note: C++ does not support default-int


  15. error C2365: 'cvReleaseCapture' : redefinition; previous definition was 'function'
    -1> c:\opencv2.3\opencv\build\include\opencv2\highgui\highgui_c.h(311) : see declaration of 'cvReleaseCapture'
    -error C2065: 'outputMovie' : undeclared identifier

  16. error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    -error C2365: 'cvReleaseVideoWriter' : redefinition; previous definition was 'function'
    -1 c:\opencv2.3\opencv\build\include\opencv2\highgui\highgui_c.h(436) : see declaration of 'cvReleaseVideoWriter'
    -error C2059: syntax error : 'return'
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========




CODE



// 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;

}



  • Kindly help to resolve the errors and issues.


  • How to do motion (human) tracking which returns the coordinates of the trajectories probably by skeletonization method.


Answer



1.) I presume you have directly copied the code from the website (correct me if I am wrong..). However since you are using OpenCV 2.3 so most of the APIs are in different modules. The following include you should have are...



#include 
#include
#include



and the respective libraries.



2.) For filtering connected components you can use cvblob library. I think the old Blob library provided by OpenCV was build using VC 6 so may be that required stdafx.h



3.) Go through the code slowly for some syntax and re-declaration error.



EDITTED CODE



#include 
#include "stdlib.h"



#include
#include
#include

#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;

}


its compiling correctly atleast...its having some run time error...I dont have a debugger to track it right now...try it...i am also trying it..


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...