此代码用于从 cam 捕获,然后在每一帧上将其转换为 HSV 图像,然后对其应用颜色分割以找到红色、绿色和蓝色对象,然后找到每个对象的轮廓并将其存储在 CVSeq 中。
代码运行良好,但问题是 10 分钟后它会引发运行时异常,因为尽管我cvClearMemStorage()
用来释放内存,但没有内存可以分配给新轮廓。
#include <cv.h>
#include <highgui.h>
CvSeq *contours;
IplImage* frame=0;
CvMemStorage* g_storage;
//This function threshold the HSV image and create a binary image
IplImage* GetThresholdedRedImage(IplImage* imgHSV)
{
IplImage* imgThresh = cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
cvInRangeS(imgHSV, cvScalar(160,160,60), cvScalar(180,256,256), imgThresh);
//CvMemStorage* g_storage = cvCreateMemStorage(0);
cvFindContours( cvCloneImage(imgThresh), g_storage, &contours );
if( contours )
{
cvDrawContours(frame, contours, cvScalar(0, 255, 0), cvScalarAll(255), 100);
cvClearSeq(contours);
}
cvClearMemStorage(g_storage);
return imgThresh;
}
IplImage* GetThresholdedGreenImage(IplImage* imgHSV)
{
IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
cvInRangeS(imgHSV, cvScalar(38,160,60), cvScalar(75,256,256), imgThresh);
//CvMemStorage* g_storage = cvCreateMemStorage(0);
cvFindContours( cvCloneImage(imgThresh), g_storage, &contours );
if( contours )
{
cvDrawContours(frame, contours, cvScalar(0, 255, 255), cvScalarAll(255), 100);
cvClearSeq(contours);
}
cvClearMemStorage(g_storage);
return imgThresh;
}
IplImage* GetThresholdedBlueImage(IplImage* imgHSV)
{
IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
cvInRangeS(imgHSV, cvScalar(75,160,60), cvScalar(130,256,256), imgThresh);
//CvMemStorage* g_storage = cvCreateMemStorage(0);
cvFindContours( cvCloneImage(imgThresh), g_storage, &contours );
if( contours )
{
cvDrawContours(frame, contours, cvScalarAll(255), cvScalarAll(255), 100);
cvClearSeq(contours);
}
cvClearMemStorage(g_storage);
return imgThresh;
}
int main()
{
CvCapture* capture =0;
capture = cvCaptureFromCAM(0);
if(!capture)
{
printf("Capture failure\n");
return -1;
}
//IplImage* frame=0;
cvNamedWindow("Video");
cvNamedWindow("Red");
//cvNamedWindow("Yellow");
//cvNamedWindow("Orange");
cvNamedWindow("Green");
cvNamedWindow("Blue");
//cvNamedWindow("Violet");
g_storage = cvCreateMemStorage(0);
//iterate through each frames of the video
while(true)
{
frame = cvQueryFrame(capture);
if(!frame) break;
frame = cvCloneImage(frame);
cvSmooth(frame, frame, CV_GAUSSIAN,3,3); //smooth the original image using Gaussian kernel
IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV
IplImage* redImgThresh = GetThresholdedRedImage(imgHSV);
IplImage* blueImgThresh = GetThresholdedBlueImage(imgHSV);
IplImage* greenImgThresh = GetThresholdedGreenImage(imgHSV);
//cvClearSeq(contours);
cvSmooth(redImgThresh, redImgThresh, CV_GAUSSIAN,3,3); //smooth the binary image using Gaussian kernel
cvSmooth(blueImgThresh, blueImgThresh, CV_GAUSSIAN,3,3);
cvSmooth(greenImgThresh, greenImgThresh, CV_GAUSSIAN,3,3);
cvShowImage("Red", redImgThresh);
cvShowImage("blue", blueImgThresh);
cvShowImage("green", greenImgThresh);
cvShowImage("Video", frame);
//Clean up used images
cvReleaseImage(&imgHSV);
cvReleaseImage(&redImgThresh);
cvReleaseImage(&blueImgThresh);
cvReleaseImage(&greenImgThresh);
cvReleaseImage(&frame);
//Wait 50mS
int c = cvWaitKey(10);
//If 'ESC' is pressed, break the loop
if((char)c==27 ) break;
}
cvDestroyAllWindows() ;
cvReleaseCapture(&capture);
return 0;
}