Visual Studio 2012 C ++控制台应用程序立即退出

时间:2013-08-04 12:07:47

标签: c++ opencv console exit

我正在使用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;
    }

}
}

我的相机工作正常但仍然退出。 提前致谢

3 个答案:

答案 0 :(得分:1)

您正在将两种分配/释放内存的方式混合在一起 - malloc/freenew/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/freenew/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循环体。