【问题标题】:Error in opencv code for motion detection用于运动检测的opencv代码中的错误
【发布时间】:2012-12-27 20:41:14
【问题描述】:

我正在寻找人体运动跟踪的实现,在multiple moving object detection 中也讨论了使用差分分析和卢卡斯 kanade 光学方法从几个视频帧中提取的内容。

我找到了科学论文,发现我们必须使用连接组件filtering connected components 进行连续运动跟踪,但我不明白如何进行这个过程。我只需要skeletonization 轨迹和人类步态运动的坐标。

我在 Opencv 和 C++ 中工作,但在我的情况下,opencv 中用于对象检测的文档还不够。我来自医学背景,需要这是儿科医生项目的一部分。

我找到了这段代码motion detection 并试图执行它(还不知道它是否检测并跟踪运动)。但是,它返回这些错误,我很困惑,因为这些错误是微不足道的,而其他 cmets 提到他们能够运行此代码。但我无法减轻这些错误,也无法理解它们发生的原因。我正在使用 OpenCv2.3,以下是错误

  1. 无法打开源文件 stdafx.h
  2. 警告 C4996:“fopen”:此函数或变量可能不安全。考虑改用 fopen_s。要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS。有关详细信息,请参阅在线帮助。
  3. 错误 C2086:“CvSize imgSize”:重新定义
  4. 错误 C2065:“临时”:未声明的标识符
  5. 错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数
    • 错误 C2365:'cvReleaseImage':重新定义;以前的定义是“功能” 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':重新定义;以前的定义是“功能” 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”:未声明的标识符 -error C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数 -错误C2365:'cvReleaseImage':重新定义;以前的定义是“功能” -1> c:\opencv2.3\opencv\build\include\opencv2\core\core_c.h(87) :参见“cvReleaseImage”的声明 -error C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数 -error C2365:'cvDestroyWindow':重新定义;之前的定义是“功能”
  13. c:\opencv2.3\opencv\build\include\opencv2\highgui\highgui_c.h(136) : 参见 'cvDestroyWindow' 的声明
  14. 错误 C2440:“正在初始化”:无法从“const char [10]”转换为“int” -1> 没有可以进行这种转换的上下文 -error C2065:“输入”:未声明的标识符 -error C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int
  15. 错误 C2365:'cvReleaseCapture':重新定义;以前的定义是“功能” -1> c:\opencv2.3\opencv\build\include\opencv2\highgui\highgui_c.h(311) : 见 'cvReleaseCapture' 的声明 -error C2065: 'outputMovie' : 未声明的标识符
  16. 错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数 -错误C2365:'cvReleaseVideoWriter':重新定义;以前的定义是“功能” -1 c:\opencv2.3\opencv\build\include\opencv2\highgui\highgui_c.h(436) : 见 'cvReleaseVideoWriter' 的声明 -error 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;

}
  • 请帮助解决错误和问题。
  • 如何进行运动(人体)跟踪,可能通过骨架化方法返回轨迹的坐标。

【问题讨论】:

    标签: c++ visual-studio-2010 opencv machine-learning computer-vision


    【解决方案1】:

    就我尝试编译代码而言,我可以发现大约 3-4 个错误。

    1. 你不需要#include "stdafx.h"
    2. 您在使用cvGetSize(frame) 的那一行重新声明imgSize
    3. 最后一个括号不匹配。
    4. 您可以检查函数_itoa(),因为它没有在代码中声明。

    【讨论】:

      【解决方案2】:

      1.) 我想你已经直接从网站上复制了代码(如果我错了,请纠正我..)。但是,由于您使用的是 OpenCV 2.3,因此大多数 API 都位于不同的模块中。您应该拥有的以下内容是...

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

      以及相应的库。

      2.) 对于过滤连接的组件,您可以使用cvblob library。我认为 OpenCV 提供的旧 Blob 库是使用 VC 6 构建的,所以可能需要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;
      
      }
      

      它至少可以正确编译...它有一些运行时错误...我现在没有调试器来跟踪它...试试看...我也在尝试它..

      【讨论】:

      • 谢谢。它仍然会抛出错误(无法打开包含文件:'opencv/core/core.hpp':没有这样的文件或目录),是的,我复制了代码并进行了下面提到的修改cmets。在放置您提到的那些 API 时,它在下面给出了红色曲线。您能否调试代码,因为我无法理解 re 声明错误。我是 opencv 新手,并使用简单的程序进行练习,因此有如此高级的代码很难调试。应该强制执行。另外,如何进行骨架化过程,这段代码会做运动跟踪吗?
      • 给我一些时间来调试代码...你放在这里的代码是最后写的代码?我的意思是我需要从那个网站复制还是这个代码就足够了?
      • 这是最终代码,无需从网站复制。感谢您的时间和精力。
      • Thanx,但它通过抛出异常终止 Human.exe 中 0x7624c41f (KernelBase.dll) 处的第一次机会异常:Microsoft C++ 异常:内存位置 0x002ff228 处的 cv::Exception .. 未处理的异常位于Human.exe 中的 0x7624c41f (KernelBase.dll):Microsoft C++ 异常:内存位置 0x002ff228 处的 cv::Exception .. Human.exe 中 0x0fe8c428 处的第一次机会异常:0xC0000005:访问冲突读取位置 0xcccccccc。等等......另外,之前有什么问题以及这些异常意味着什么以便删除它们?
      • 我相信我必须录制并保存视频。我在这里找到了此代码 stackoverflow.com/questions/3400908/… ,它可以编译,但是它会在网络摄像头打开一次后终止,然后在控制台中显示“断言失败..this应用程序已请求运行时以异常方式终止它,请联系应用程序的支持团队。”怎么办?请帮忙
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-23
      • 2012-11-15
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多