2013-08-04 2 views
0

C++로 작업하는 Im OpenCV 라이브러리가있는 Visual Studio 2012에서. 문제는 콘솔 응용 프로그램을 실행할 때 약 2 ~ 3 초 후에 닫힙니다. 을 Heres 코드 : 내 카메라가 제대로 작동하고Visual Studio 2012 C++ 콘솔 응용 프로그램이 즉시 종료됩니다.

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

} 
} 

여전히 종료됩니다.

CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments)); 

delete moments; 

당신은 두 가지를 혼합하지해야합니다 malloc/freenew/delete - 사전

+1

메모리 누수, 확인되지 않은 포인터 ... 무엇을 사랑하지 않으시겠습니까? –

+0

엄지 손가락 :'포인터 연산을위한 포인터 사용, 다른 모든 것에 대한 참조 ' –

+2

메모리를 할당하기 위해'malloc'을 사용하고, 메모리를 할당하기 위해'delete'를 사용하고 있습니다. – lapk

답변

1

에서 덕분에 당신은 할당/해제 메모리의 두 가지 방법을 함께 혼합된다. malloc/free 할당 된 메모리에서 생성자/소멸자를 호출하지 마십시오. new/delete 할당 된 메모리에 생성자/소멸자를 호출하고 malloc/free 대신 다른 메모리 함수를 사용하여 실제 메모리를 할당하거나 해제 할 수 있습니다. 결과적으로, 비 구조 객체의 소멸자를 호출하는 것부터 비 대응 함수를 사용하여 메모리를 할당/해제하는 것까지 모든 종류의 오류가 발생할 수 있습니다.

플러스 다른 문제가있을 수 있습니다. 이것은 명백한 것이므로 그것을 고쳐서 시작해야합니다.

EDIT # 1 : 위에서 말한 모든 것이 사실이고 수정해야하지만, Andrey Smorodov's answer, 아마, 그것을 내었을 것입니다 : 무조건 loop 내부에서 return. 내가 malloc/delete 문제를 본 후 코드 검사를 중단해서는 안됩니다;).

편집 # 2 : 귀하의 의견에 답변하십시오. CvMoments이 C 구조체 인 경우 delete 대신 free을 사용하십시오. C++ 클래스 인 경우 malloc 대신 new을 사용하십시오.

또한 루프가 끝날 때 코드를 검토해야합니다. 당신이 거기서하고 싶은 것을 말하기는 어렵습니다. 그것의 모습으로, 나는 루프 이전에 moments을위한 메모리 할당을하고 루프 이후의 자유 메모리 - 같은 크기의 메모리를 계속 할당/해제한다. 심지어 힙에 그것을 필요로합니까? 스택에 넣을 수는 없습니까? 또한 사용자가 키를 누를 때까지 계속 카메라로 작업하고 싶어합니다. 사용자가 키를 누르거나 기다릴 때마다 매번 카메라를 놓아야합니까? 어떤 경우에는 제어가 if 문으로 넘어 가기 전에 return 문이 루프를 종료하고 main (및 프로그램)을 종료합니다. 루프 외부에 return 문을 둡니다.

한마디로

: 루프 전에

- 메모리를 할당합니다. malloc/free 또는 new/delete을 사용해야하지만 혼합하지 마십시오. 전혀 힙이 필요한지 생각해보십시오. 아마도 스택은 괜찮습니다.

루프에서 - 여유 메모리를 제거하고 해제 카메라를 제거한 후 return을 제거하십시오. 루프를 통해 다음 단계에 사용하게 될 것입니다. 사용자가 루프 안의 키를 누르면 루프 밖으로 빠져 나옵니다.

루프가 끝나면 이제 정리하고 싶습니다. 사용 가능한 메모리, 해제 카메라, return에서 main.

+0

답변 주셔서 감사합니다.하지만 문제를 해결할 수있는 방법을 알려주십시오. –

+0

@MatthewC 게시물에 수정 사항을 추가했습니다. 당신이 정확히 무엇을 필요로하는지 말하기는 어렵지만 한번보세요. 건배. – lapk

1

Malloc과 delete를 함께 사용할 수 없으므로 free (ptr)를 대신 사용하십시오.

1

나는

// We're done using the camera. Other applications can now use it 

cvReleaseCapture (& 캡처) 생각;

return 0;

은 while 루프를 벗어나 있어야합니다.

관련 문제