我正在使用C ++在Visual Studio 2012中使用OpenCV库。 问题是,当我运行我的控制台应用程序时,大约2或3秒后它关闭。 下面是代码:
#include "cv.h"
#include "highgui.h"
IplImage* GetThresholdedImage(IplImage *img)
{
// Convert the image into an HSV image
IplImage* imgHSV = cvCreateImage(cvGetSize(img), 8, 3);
cvCvtColor(img, imgHSV, CV_BGR2HSV);
IplImage* imgThreshed = cvCreateImage(cvGetSize(img), 8, 1);
cvInRangeS(imgHSV, cvScalar(20, 100, 100), cvScalar(30, 255, 255), imgThreshed); //Detect Colour
cvReleaseImage(&imgHSV);
return imgThreshed;
}
int main()
{
// Initialize capturing live feed from the camera
CvCapture* capture = 0;
capture = cvCaptureFromCAM(0); // cvCaptureFromCAM(0) indicates camera being used, Change the 0 for a different camera
// Couldn't get a device? Throw an error and quit
if(!capture)
{
printf("Camera not working\n");
return -1;
}
// The two windows we'll be using
cvNamedWindow("video"); //Create new window containing video
cvNamedWindow("thresh"); //Create another window containing thresholded image
// This image holds the "scribble" data
// the tracked positions of the ball
IplImage* imgScribble = NULL;
// An infinite loop
while(true)
{
// Will hold a frame captured from the camera
IplImage* frame = 0;
frame = cvQueryFrame(capture);
// If we couldn't grab a frame... quit
if(!frame)
printf("Couldnt get frame \n");
// If this is the first frame, we need to initialize it
if(imgScribble == NULL)
{
imgScribble = cvCreateImage(cvGetSize(frame), 8, 3);
}
// Holds the yellow thresholded image (yellow = white, rest = black)
IplImage* imgYellowThresh = GetThresholdedImage(frame);
// Calculate the moments to estimate the position of the ball
CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
cvMoments(imgYellowThresh, moments, 1);
// The actual moment values
double moment10 = cvGetSpatialMoment(moments, 1, 0);
double moment01 = cvGetSpatialMoment(moments, 0, 1);
double area = cvGetCentralMoment(moments, 0, 0);
// Holding the last and current ball positions
static int posX = 0;
static int posY = 0;
int lastX = posX;
int lastY = posY;
posX = moment10/area;
posY = moment01/area;
// Print it out for debugging purposes
printf("position (%d,%d)\n", posX, posY);
// We want to draw a line only if its a valid position
if(lastX>0 && lastY>0 && posX>0 && posY>0)
{
// Draw a yellow line from the previous point to the current point
cvLine(imgScribble, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,255,255), 5);
}
// Add the scribbling image and the frame
cvAdd(frame, imgScribble, frame);
cvShowImage("thresh", imgYellowThresh);
cvShowImage("video", frame);
// Release the thresholded image+moments we need no memory leaks please
cvReleaseImage(&imgYellowThresh);
delete moments;
// We're done using the camera. Other applications can now use it
cvReleaseCapture(&capture);
return 0;
// Wait for a keypress
int c = cvWaitKey(10);
if(c!=-1)
{
// If pressed, break out of the loop
break;
}
}
}
我的相机工作正常但仍然退出。 提前致谢
答案 0 :(得分:1)
您正在将两种分配/释放内存的方式混合在一起 - malloc/free
和new/delete
:
CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
和
delete moments;
你不应该混淆两者。 malloc/free
不要在分配的内存上调用构造函数/析构函数。 new/delete
在分配的内存上调用构造函数/析构函数,并且可能使用其他内存函数而不是malloc/free
来分配/释放实际内存。因此,您可以从在未构造对象上调用析构函数到使用非对应函数分配/释放内存等各种原因发出各种错误。
另外,当然还有其他问题。这是一个显而易见的问题,你应该从修复它开始。
编辑#1:虽然上面说的所有内容都是正确的并且应该修复,Andrey Smorodov's answer可能会将其钉住:你在循环内无条件return
。在看到malloc/delete
问题后,我不应该停止检查您的代码;)。
编辑#2:回答你的评论。
如果CvMoments
是C结构,请使用free
代替delete
。如果是C ++类,请使用new
而不是malloc
。
您还必须在循环结束时查看代码。很难说你想做什么。从它的外观来看,我会在循环之前为moments
分配内存并在循环之后释放内存 - 你继续分配/释放相同数量的内存。你甚至需要在堆上吗?你能不能把它放在堆栈上吗?在用户按下某个键之前,您似乎还想继续使用相机。您是否需要在用户按下某个键之后或每次开始等待之前释放相机?在任何情况下,在控制转到return
语句之前,您的main
语句退出循环并if
(和程序)。将return
语句放在循环外。
简而言之:
在循环之前 - 分配内存。请务必使用malloc/free
或new/delete
,但不要混用它们。想想你是否需要堆,也许堆栈是可以的。
循环 - 删除释放内存,删除释放相机,删除return
。你将在下一次循环中使用它们,对吗?如果用户按下一个键(在循环内),你就会离开循环。
循环之后 - 现在你真的想要清理。可用内存,从return
发布相机main
。
答案 1 :(得分:1)
Malloc和delete不能一起使用,而是使用free(ptr)。
答案 2 :(得分:1)
我认为
// We're done using the camera. Other applications can now use it
cvReleaseCapture(安培;捕捉);
返回0;
必须超出while循环体。