Reputation: 91
Im working with C++ In Visual Studio 2012 with the OpenCV library. The problem is that when I run my console application, after about 2 or 3 seconds it closes. Heres the code:
#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;
}
}
}
My Camera is working properly and it still quits. Thanks in advance
Upvotes: 0
Views: 767
Reputation: 3918
You are mixing together two ways of allocating/freeing memory - malloc/free
and new/delete
:
CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
and
delete moments;
You should not mix the two. malloc/free
do not call constructor/destructor on the allocated memory. new/delete
do call constructor/destructor on the allocated memory, and MIGHT be using other memory function instead of malloc/free
to allocate/free the actual memory. As a result, you can get all sorts of errors emanating from reasons ranging from calling a destructor on unconstructed object to using non-corresponding functions to allocate/free memory.
Plus, there can be other problems, of course. This is an obvious one and you should start by fixing it.
EDIT #1: While everything said above is true and should be fixed, Andrey Smorodov's answer, probably, nailed it: you unconditionally return
from inside the loop. I should've not stopped checking your code after I saw malloc/delete
problem ;).
EDIT #2: To answer your comment.
If CvMoments
is a C-struct, use free
instead of delete
. If it is a C++ class, use new
instead of malloc
.
You also have to review the code in the end of your loop. It is hard to say what you want to do there. By the looks of it, I would put memory allocation for moments
before the loop and free memory after the loop - you keep allocating/freeing same amount of memory. Do you even need it on heap? Can you not just put it on stack? It also seems that you want to keep working with camera until user pressed a key. Do you need to release camera AFTER user pressed a key or every time before you start waiting for it? In any case, your return
statement exits the loop and main
(and program) before control goes to if
statement. Put return
statement OUTSIDE the loop.
In short:
Before loop - allocate memory. Remember to use malloc/free
or new/delete
, but do not mix them. Think if you need heap at all, maybe stack is ok.
In loop - remove freeing memory, remove releasing camera, remove return
. You will be using them on the next go through the loop, right? If user presses a key (inside the loop), you'll go out of the loop.
After the loop - now you really want to clean up. Free memory, release camera, return
from main
.
Upvotes: 1
Reputation: 10852
I think
// We're done using the camera. Other applications can now use it
cvReleaseCapture(&capture);
return 0;
must be out of while loop body.
Upvotes: 1
Reputation: 847
Malloc and delete cannot be used together, use free(ptr) instead.
Upvotes: 1