Обнаружение круга и руки в OpenCV - PullRequest
2 голосов
/ 03 марта 2011

Начинающий здесь. Я пытаюсь определить круг и руку, нарисовать круг вокруг круга и прямоугольник вокруг руки и отобразить оба изображения на одном и том же изображении. Когда я запускаю программу, у меня возникает ошибка памяти, может кто-нибудь помочь?

Ниже мой код:

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

Ответы [ 3 ]

2 голосов
/ 07 апреля 2011

Проблема заключается в том, что размер создаваемого серого изображения должен быть таким же, как и размер изображения, полученного с камеры.

Вместо:

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

напишите как:

IplImage *gray = cvCreateImage( cvSize(img->width,img->height), 8, 1);
1 голос
/ 03 марта 2011

Из сообщения об ошибке кажется, что вы читаете элементы p[], которых не существует.

Вы должны проверить, что cvGetSeqElem() действительно возвращает количество ожидаемых вами элементов - это может бытьчто рутины Хафа не находят ничего.

0 голосов
/ 11 июня 2013

У меня такая же ошибка! Вы должны добавить в свой код оператор 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 
    );
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...