2011-03-02 81 views
2

初学者在这里。我试图发现一个圆圈,手,画周围一圈一圈和周围的手一个矩形,并同时显示在相同的图像。当我运行该程序时,出现一些内存错误,任何人都可以请帮忙吗?圈和手检测在OpenCV中

下面是我的代码:

#include "opencv/cv.h" 
#include "opencv2\highgui\highgui.hpp" 
#include <iostream> 
#include <stdio.h> 
#include <math.h> 
#include <string.h> 
#include <conio.h> 

using namespace std; 

//declarations 
IplImage* img = 0; 

CvHaarClassifierCascade *cascade; 
CvMemStorage *cstorage; 
CvMemStorage *hstorage; 

void detectObjects(IplImage *img); 
int key; 

int main(int argc, char** argv) 
{ 
CvCapture *capture; 
IplImage *frame; 

// loads classifier for hand haar cascade 
char *filename = "haarcascade_hand.xml"; 
cascade = (CvHaarClassifierCascade*)cvLoad("haarcascade_hand.xml", 0, 0, 0); 

// setup memory buffer 
hstorage = cvCreateMemStorage(0); 
cstorage = cvCreateMemStorage(0); 

// initialize camera 
capture = cvCaptureFromCAM(0); 

// always check 
//assert(cascade && storage && capture); 

// create a window 
cvNamedWindow("Camera", 1); 

while(key!='q') { 
    // captures frame and check every frame 
    frame = cvQueryFrame(capture); 
    if(!frame) break; 

    // detect objects and display video 
    detectObjects (frame); 

    // quit if user press 'q' 
    key = cvWaitKey(10); 
} 

// free memory 
cvReleaseCapture(&capture); 
cvDestroyAllWindows(); 
cvReleaseHaarClassifierCascade(&cascade); 
cvReleaseMemStorage(&cstorage); 
cvReleaseMemStorage(&hstorage); 

return 0; 
} 

void detectObjects(IplImage *img) 
{ 
int px; 
int py; 
int edge_thresh = 1; 
IplImage *gray = cvCreateImage(cvSize(640,480), 8, 1); 
IplImage *edge = cvCreateImage(cvSize(640,480), 8, 1); 

// convert video image color 
cvCvtColor(img,gray,CV_BGR2GRAY);      

// set the converted image's origin 
gray->origin=1;       

// color threshold 
cvThreshold(gray,gray,100,255,CV_THRESH_BINARY);  

// smooths out image 
cvSmooth(gray, gray, CV_GAUSSIAN, 11, 11); 

// get edges 
cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 5); 

// detects circle 
CvSeq* circle = cvHoughCircles(gray, cstorage, CV_HOUGH_GRADIENT, 1, gray->height/50, 5, 35); 

// draws circle and its centerpoint 
float* p = (float*)cvGetSeqElem(circle, 0); 
cvCircle(img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(255,0,0), -1, 8, 0); 
cvCircle(img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(200,0,0), 1, 8, 0); 
px=cvRound(p[0]); 
py=cvRound(p[1]); 

// displays coordinates of circle's center 
cout <<"(x,y) -> ("<<px<<","<<py<<")"<<endl; 

// detects hand 
CvSeq *hand = cvHaarDetectObjects(img, cascade, hstorage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(100, 100)); 

// draws red box around hand when detected 
CvRect *r = (CvRect*)cvGetSeqElem(hand, 0); 
cvRectangle(img, 
    cvPoint(r->x, r->y), 
    cvPoint(r->x + r->width, r->y + r->height), 
    CV_RGB(255, 0, 0), 1, 8, 0); 

cvShowImage("Camera",img); 
} 
+2

,如果你给实际的错误信息和行号这将有助于(如果有的话) – 2011-03-02 21:25:34

+0

@马丁贝克特 的错误是在Test2.exe在0x013e56af“未处理的异常: 0000005:访问冲突读取位置0x00000004“。在线94上,即: cvCircle(img,cvPoint(cvRound(p [0]),cvRound(p [1])),3,CV_RGB(255,0,0),-1,8,0); 谢谢! – Bob 2011-03-03 03:28:12

回答

1

从错误消息,似乎你正在阅读的是不存在的p[]元素。

你应该检查cvGetSeqElem()实际上返回你期望元素的数量 - 这可能是因为霍夫例程中没有发现任何。

2

的问题是,产生的灰度图像的大小应该是相同的为从照相机获得的图像的。

相反的:

IplImage *gray = cvCreateImage(cvSize(640,480), 8, 1); 

把它写成:

IplImage *gray = cvCreateImage(cvSize(img->width,img->height), 8, 1); 
0

我有同样的错误!你必须添加到您的代码中的if语句,因为当相机启动无法“看到”任何手部,使得cvGetSeqElem得不到值。 试试这个:

if (hand->total >0) { 
    CvRect *r = (CvRect*)cvGetSeqElem(hand, 0); 
    cvRectangle( 
     img, 
     cvPoint(r->x, r->y), 
     cvPoint(r->x + r->width, r->y + r->height), 
     CV_RGB(255, 0, 0), 1, 8, 0 
    ); 
}