openCV and Threads issue - c++

I'm trying to fit facedetect from openCV on my QT code, all run fine until i decided to create a thread for my openCV code so I can run another things while the face detect is on.
the problem is if i call class->start(); my program breaks in the while loop in the run() but if i call the class.run(); (like a normal function) it runs as usual! what can be wrong?
code:
faceTracker::faceTracker()
{
qDebug("teste1");
filename = "/Users/marcomartins/Documents/QT/DisplUM/haarcascades/haarcascade_frontalface_alt_tree.xml";
/* load the classifier
note that I put the file in the same directory with this code */
cascade = ( CvHaarClassifierCascade* )cvLoad( filename, 0, 0, 0 );
/* setup memory buffer; needed by the face detector */
storage = cvCreateMemStorage( 0 );
/* initialize camera */
capture = cvCaptureFromCAM( 0 );
/* always check */
assert( cascade && storage && capture );
/* create a window */
cvNamedWindow( "video DisplUM", 1 );
}
void faceTracker::detectFaces( IplImage *img )
{
/* detect faces */
faces = cvHaarDetectObjects(
img,
cascade,
storage,
1.1,
3,
0 /*CV_HAAR_DO_CANNY_PRUNNING*/,
cvSize( 40, 40 ) );
/* for each face found, draw a red box */
for( i = 0 ; i < ( faces ? faces->total : 0 ) ; i++ ) {
CvRect *r = ( CvRect* )cvGetSeqElem( faces, i );
cvRectangle( img,
cvPoint( r->x, r->y ),
cvPoint( r->x + r->width, r->y + r->height ),
CV_RGB( 255, 0, 0 ), 1, 8, 0 );
qDebug("caras: %d", faces->total);
}
/* display video */
cvShowImage( "video", img );
}
void faceTracker::run( )
{
qDebug("teste2");
while( key != 'q' ) {
/* get a frame */
frame = cvQueryFrame( capture );
qDebug("teste3");
/* always check */
if( !frame ) break;
/* 'fix' frame */
cvFlip( frame, frame, 1 );
frame->origin = 0;
/* detect faces and display video */
detectFaces( frame );
/* quit if user press 'q' */
key = cvWaitKey( 10 );
}
/* free memory */
cvReleaseCapture( &capture );
cvDestroyWindow( "video" );
cvReleaseHaarClassifierCascade( &cascade );
cvReleaseMemStorage( &storage );
}
main code:
int main(int argc, char *argv[])
{
faceTracker * ft = new faceTracker();
ft->start();
}
thanks a lot!

The loop will only break if cvQueryFrame() returns a NULL frame or if the user presses q on the keyboard.
Add a debug so you know when the first situation happens:
frame = cvQueryFrame( capture );
if( !frame )
{
qDebug("cvQueryFrame failed!");
break;
}
Are you sure cvCaptureFromCAM(0) works ? Depending on the OS I have to pass -1 for it. But the fact is that you'll never know if cvCaptureFromCAM(0)succeeded because you don't check the return, and this might be the problem!
capture = cvCaptureFromCAM(0);
if (!capture)
{
qDebug("cvCaptureFromCAM failed!");
//exit(0); or whatever
}
EDIT:
Pay huge attention to this: you are creating a window named "video DisplUM" but you are trying to display the frames on a different window, named "video".
Anyway, it's also better if you change the window creation function to use the appropriate enum:
cvNamedWindow("video DisplUM", CV_WINDOW_AUTOSIZE);
and on faceTracker::run( ) comment detectFaces() for now and add a call to cvShowImage( "video DisplUM", frame );
Always be sure your application works with the minimum requirements before adding fancy stuffs, like face detection. My final suggestion is: write enough code just to capture the images from one thread and display them on a window, and then go from there.

Solution:
I can't create windows outside the main thread, that is why it was crashing. If i comment the window creation all works good (face detection included)

I ran into a similar issue. What I found is that I had to rebuild OpenCV and include the TBB libraries. This adds threading support to OpenCV. Once I did this, I was able to pop up windows in any thread I chose. I've tested this on versions 2.1 and 2.2, using both C and C++ implementations.

Related

Eye Blinking Detection

Some warnings appear in terminal during running:
OpenCV Error: Assertion failed(s>=0) in setSize, file /home/me/opencv2.4/modules/core/src/matrix.cpp, line 116
The program compiled without error and executes, the problem is the eye ROI size changes when user moves closer/farther away from webcam, due to the changing of size, the warning appears. I managed to solve these warnings by setting the eye ROI size equal to my eye template size. However, it ends up the program fails to classify user's eyes open/close because the minVal obtained is 0. The method used is OpenCV Template Matching. Alternatively, I fix my distance from webcam and fix the eye template size could avoid the warning. Every time warning appears, the program fails to classify open/close eyes. The program doesn't work effectively because sometimes it mistakenly classifies the open eyes as closed and vice versa.
Questions:
Is there any alternative to identify open and close eyes other than template matching?
Any ideas how to improve the program in classification of blinking?
Any working example that you know in opencv C/C++ API can classify open and close eyes and count accurately the blinking times?
static CvMemStorage* storage = 0;
// Create a new Haar classifier
static CvHaarClassifierCascade* cascade = 0;
// Function prototype for detecting and drawing an object from an image
bool detect_and_draw( IplImage* image ,CvHaarClassifierCascade* cascade);
const char *cascade_name[1]={"eyes.xml"};
cv::Mat roiImg;
int threshold_value = 200;
int threshold_type = 3;;
int const max_value = 255;
int const max_type = 4;
int const max_BINARY_value = 255;
int hough_thr = 35;
cv::Mat src_gray, dst;
using namespace cv;
Mat img1; Mat img2; Mat templ; Mat result;
const char* image_window = "Source Image";
const char* result_window = "Result window";
int match_method=0;
int max_Trackbar = 5;
int eye_open=0;
int eye_close=0;
//Matching with 2 images ,eye closed or open
void MatchingMethod(cv::Mat templ,int id )
{
/// Source image to display
cv::Mat img_display;
roiImg.copyTo( img_display );
/// Create the result matrix
int result_cols = roiImg.cols - templ.cols + 1;
int result_rows = roiImg.rows - templ.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize
cv::matchTemplate( roiImg, templ, result, match_method );
cv::normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
/// Localizing the best match with minMaxLoc
double minVal; double maxVal; Point minLoc; Point maxLoc;
cv::Point matchLoc;
cv::minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
///Justing checkin the match template value reaching the threashold
if(id == 0 && (minVal < 0))
{
eye_open=eye_open+1;
if(eye_open == 1)
{
std::cout<<"Eye Open"<<std::endl;
eye_open=0;
eye_close=0;
}
}
else if(id == 1 && (minVal < 0))
eye_close=eye_close+1;
if(eye_close == 1)
{
std::cout<<"Eye Closed"<<std::endl;
eye_close=0;
system("python send_arduino.py");
}
/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{ matchLoc = minLoc; }
else
{ matchLoc = maxLoc; }
/// Show me what you got
cv::rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
cv::rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
cv::imshow( image_window, img_display );
cv::imshow( result_window, result );
return;
}
void detect_blink(cv::Mat roi)
{
try
{
MatchingMethod(img1,0);
MatchingMethod(img2,1);
}
catch( cv::Exception& e )
{
std::cout<<"An exception occued"<<std::endl;
}
}
// Main function, defines the entry point for the program.
int main( int argc, char** argv )
{
if(argc <= 1)
{
std::cout<<"\n Help "<<std::endl;
std::cout<<"\n ------------------------------------\n"<<std::endl;
std::cout<<"./blink_detect open_eye.jpg close_eye.jpg\n"<<std::endl;
std::cout<<"Eg :: ./blink_detect 2.jpg 3.jpg\n"<<std::endl;
std::cout<<"\n ------------------------------------\n"<<std::endl;
exit(0);
}
// Structure for getting video from camera or avi
CvCapture* capture = 0;
// Images to capture the frame from video or camera or from file
IplImage *frame, *frame_copy = 0;
// Used for calculations
int optlen = strlen("--cascade=");
// Input file name for avi or image file.
const char* input_name;
img1 = imread( argv[1], 1 );
img2 = imread( argv[2], 1 );
// Load the HaarClassifierCascade
/// Create windows
cv::namedWindow( image_window, CV_WINDOW_AUTOSIZE );
cv::namedWindow( result_window, CV_WINDOW_AUTOSIZE );
// Allocate the memory storage
storage = cvCreateMemStorage(0);
capture = cvCaptureFromCAM( 0);
// Create a new named window with title: result
cvNamedWindow( "original_frame", 1 );
// If loaded succesfully, then:
if( capture )
{
// Capture from the camera.
for(;;)
{
// Capture the frame and load it in IplImage
if( !cvGrabFrame( capture ))
break;
frame = cvRetrieveFrame( capture );
// If the frame does not exist, quit the loop
if( !frame )
break;
// Allocate framecopy as the same size of the frame
if( !frame_copy )
frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
IPL_DEPTH_8U, frame->nChannels );
// Check the origin of image. If top left, copy the image frame to frame_copy.
if( frame->origin == IPL_ORIGIN_TL )
cvCopy( frame, frame_copy, 0 );
// Else flip and copy the image
for(int i=0;i<1;i++)
{
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name[i], 0, 0, 0 );
// Check whether the cascade has loaded successfully. Else report and error and quit
if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
return -1;
}
// Call the function to detect and draw the face
if(detect_and_draw(frame_copy,cascade))
{
std::cout<<"Detected"<<std::endl;
}
}
// Wait for a while before proceeding to the next frame
if( cvWaitKey( 1 ) >= 0 )
break;
}
// Release the images, and capture memory
cvReleaseHaarClassifierCascade(&cascade);
cvReleaseImage( &frame_copy );
cvReleaseCapture( &capture );
cvReleaseMemStorage(&storage);
}
return 0;
}
// Function to detect and draw any faces that is present in an image
bool detect_and_draw( IplImage* img,CvHaarClassifierCascade* cascade )
{
int scale = 1;
// Create a new image based on the input image
IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );
// Create two points to represent the face locations
CvPoint pt1, pt2;
int i;
// Clear the memory storage which was used before
cvClearMemStorage( storage );
// Find whether the cascade is loaded, to find the faces. If yes, then:
if( cascade )
{
// There can be more than one face in an image. So create a growable sequence of faces.
// Detect the objects and store them in the sequence
CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
1.1, 8, CV_HAAR_DO_CANNY_PRUNING,
cvSize(40, 40) );
// Loop the number of faces found.
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
// Create a new rectangle for drawing the face
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
// Find the dimensions of the face,and scale it if necessary
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
// Draw the rectangle in the input image
cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
cv::Mat image(img);
cv::Rect rect;
rect = cv::Rect(pt1.x,pt1.y,(pt2.x-pt1.x),(pt2.y-pt1.y));
roiImg = image(rect);
cv::imshow("roi",roiImg);
///Send to arduino
detect_blink(roiImg);
}
}
cvShowImage( "original_frame", img );
if(i > 0)
return 1;
else
return 0;
cvReleaseImage( &temp );
}
Reference:
Website referred

Visual C++ express 2010 The procedure entry point ??1task_group_context#tbb##QAE#XZ could not be located in the dynamic link library tbb.dll

Can someone help me out with this error?
I tried researching on the internet and tried the different methods to resolve the problem (eg: uninstalling other versions of visual c++, adding codes, etc), but none of them seem to work :(
What I have done:
under c/c++-->general-->additional include directories-->C:\OpenCV2.3\build\include;C:\OpenCV2.3\build\include\opencv2;C:\OpenCV2.3\build\include\opencv;C:\OpenCV2.3\opencv\data\haarcascades
under linker-->general-->additional library directories-->C:\OpenCV2.3\build\x86\vc9\lib;C:\OpenCV2.3\opencv\data\haarcascades;%(AdditionalLibraryDirectories)
under linker-->input-->additional dependencies--> added opencv_core230.lib;opencv_highgui230.lib;opencv_objdetect230.lib
under debugging-->command arguments -->added --cascade="C:/Program Files/OpenCV/data/haarcascades/haarcascade_frontalface_alt.xml"testimg.jpg
The code:
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
// Create memory for calculations
static CvMemStorage* storage = 0;
// Create a new Haar classifier
static CvHaarClassifierCascade* cascade = 0;
// Function prototype for detecting and drawing an object from an image
void detect_and_draw( IplImage* image );
// Create a string that contains the cascade name
const char* cascade_name = "haarcascade_frontalface_alt.xml";
/* "haarcascade_profileface.xml";*/
// Main function, defines the entry point for the program.
int main( int argc, char** argv )
{
// Structure for getting video from camera or avi
CvCapture* capture = 0;
// Images to capture the frame from video or camera or from file
IplImage *frame, *frame_copy = 0;
/* IplImage* img = cvLoadImage( "testimg.jpg" );
cvNamedWindow( "MyJPG", CV_WINDOW_AUTOSIZE );
cvShowImage("MyJPG", img);
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow( "MyJPG" );
*/
// Used for calculations
int optlen = strlen("--cascade=");
// Input file name for avi or image file.
const char* input_name;
// Check for the correct usage of the command line
if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )
{
cascade_name = argv[1] + optlen;
input_name = argc > 2 ? argv[2] : 0;
}
else
{
fprintf( stderr,
"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
return -1;
/*input_name = argc > 1 ? argv[1] : 0;*/
}
// Load the HaarClassifierCascade
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
// Check whether the cascade has loaded successfully. Else report and error and quit
if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
return -1;
}
// Allocate the memory storage
storage = cvCreateMemStorage(0);
// Find whether to detect the object from file or from camera.
if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') )
capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
else
capture = cvCaptureFromAVI( input_name );
// Create a new named window with title: result
cvNamedWindow( "result", 1 );
// Find if the capture is loaded successfully or not.
// If loaded succesfully, then:
if( capture )
{
// Capture from the camera.
for(;;)
{
// Capture the frame and load it in IplImage
if( !cvGrabFrame( capture ))
break;
frame = cvRetrieveFrame( capture );
// If the frame does not exist, quit the loop
if( !frame )
break;
// Allocate framecopy as the same size of the frame
if( !frame_copy )
frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
IPL_DEPTH_8U, frame->nChannels );
// Check the origin of image. If top left, copy the image frame to frame_copy.
if( frame->origin == IPL_ORIGIN_TL )
cvCopy( frame, frame_copy, 0 );
// Else flip and copy the image
else
cvFlip( frame, frame_copy, 0 );
// Call the function to detect and draw the face
detect_and_draw( frame_copy );
// Wait for a while before proceeding to the next frame
if( cvWaitKey( 10 ) >= 0 )
break;
}
// Release the images, and capture memory
cvReleaseImage( &frame_copy );
cvReleaseCapture( &capture );
}
// If the capture is not loaded succesfully, then:
else
{
// Assume the image to be lena.jpg, or the input_name specified
const char* filename = input_name ? input_name : (char*)"testimg.jpg";
// Load the image from that filename
IplImage* image = cvLoadImage( filename, 1 );
// If Image is loaded succesfully, then:
if( image )
{
// Detect and draw the face
detect_and_draw( image );
// Wait for user input
cvWaitKey(0);
// Release the image memory
cvReleaseImage( &image );
}
else
{
/* assume it is a text file containing the
list of the image filenames to be processed - one per line */
FILE* f = fopen( filename, "rt" );
if( f )
{
char buf[1000+1];
// Get the line from the file
while( fgets( buf, 1000, f ) )
{
// Remove the spaces if any, and clean up the name
int len = (int)strlen(buf);
while( len > 0 && isspace(buf[len-1]) )
len--;
buf[len] = '\0';
// Load the image from the filename present in the buffer
image = cvLoadImage( buf, 1 );
// If the image was loaded succesfully, then:
if( image )
{
// Detect and draw the face from the image
detect_and_draw( image );
// Wait for the user input, and release the memory
cvWaitKey(0);
cvReleaseImage( &image );
}
}
// Close the file
fclose(f);
}
}
}
// Destroy the window previously created with filename: "result"
cvDestroyWindow("result");
// return 0 to indicate successfull execution of the program
return 0;
}
// Function to detect and draw any faces that is present in an image
void detect_and_draw( IplImage* img )
{
int scale = 1;
// Create a new image based on the input image
IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), 8, 3 );
// Create two points to represent the face locations
CvPoint pt1, pt2;
int i;
// Clear the memory storage which was used before
cvClearMemStorage( storage );
// Find whether the cascade is loaded, to find the faces. If yes, then:
if( cascade )
{
// There can be more than one face in an image. So create a growable sequence of faces.
// Detect the objects and store them in the sequence
CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
cvSize(40, 40) );
// Loop the number of faces found.
for( i = 0; i < (faces ? faces->total : 0); i++ )
{
// Create a new rectangle for drawing the face
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
// Find the dimensions of the face,and scale it if necessary
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
// Draw the rectangle in the input image
cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
}
}
// Show the image in the window named "result"
cvShowImage( "result", img );
// Release the temp image created.
cvReleaseImage( &temp );
}
The error message says, that a certain symbol could not be found in an external library, tbb.dll. The library (the dll) itself seems to be found.
The library is Threading building blocks and your error message hints to a mismatch between header and the used dll, for example because of multiple versions installed etc. You should find out, if the correct dll is used at runtime (check the modules window in VS, or use Dependency Walker for that).
To point the runtime application to the correct path of tbb.dll, you might put the directory in your PATH environment variable, or put the tbb.dll side by side to the Executable.

opencv - cvCaptureFromCAM(CV_CAP_DSHOW) capture blank frame

I am using OpenCV 2.1 and Visual Studio 2008 in Windows. I am trying to grab the frames from CCD camera and want to display on Windows. Camera is with PAL format. Camera is detecting but showing the blank grey screen.
I found many post related to blank screen but no one is work in my case. So post I post this question.
Below is my code:
#include "stdafx.h"
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
int main(int argc, char* argv[])
{
cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
CvCapture* capture = cvCaptureFromCAM(CV_CAP_DSHOW);
if ( !capture ) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
return -1;
}
while ( 1 ) {
IplImage* frame = cvQueryFrame( capture );
if ( !frame ) {
fprintf( stderr, "ERROR: frame is null...\n" );
getchar();
break;
}
else
{
fprintf( stderr, "Size of camera frame %d X %d\n",frame->width,frame->height );
}
cvShowImage( "mywindow", frame );
if ( (cvWaitKey(10) & 255) == 27 ) break;
}
// Release the capture device housekeeping
cvReleaseCapture( &capture );
cvDestroyWindow("mywindow");
return 0;
}
Above code return frame size 320 X 240 but blank screen.
Code is working fine for usb webcam with code CvCapture* capture = cvCaptureFromCAM(1);
I am using Avermedia Gold Camera Card on my board. So Do I need SDK to use this camera or is there any option to use CCD camera??
Driver is installed correctly and check with EzCaptureVC application.
OpenCV needs to support your camera else there's no guarantee its going to work: check the compatibility list.
Also 2.1 it's very outdated. I suggest you try again with the 2.3.1 since there has been some improvements in this area.

Wanting to live-mirror video in OpenCV on OSX, not sure where to start

If it isn't already obvious, this is my first day playing around with OpenCV.
What I am hoping to do is mirror frame2, and then upsample it.
I am not sure how to use a matrix operation on these frames which are of type IplImage. How could I mirror my frame2, and then upsample it to the Webcam2 window? Below is my code:
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
// A Simple Camera Capture Framework
int main() {
CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
if ( !capture ) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
return -1;
}
// Create a window in which the captured images will be presented
cvNamedWindow( "Webcam", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "Webcam2", CV_WINDOW_AUTOSIZE );
// Show the image captured from the camera in the window and repeat
while ( 1 ) {
// Get one frame
IplImage* frame = cvQueryFrame( capture );
IplImage* frame2 = cvCreateImage(cvSize (frame->width*2, frame->height*2),
frame->depth, frame->nChannels);
cvPyrUp (frame, frame2);
if ( !frame ) {
fprintf( stderr, "ERROR: frame is null...\n" );
getchar();
break;
}
cvShowImage( "Webcam", frame );
cvShowImage( "Webcam2", frame2 );
// Do not release the frame!
//If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
//remove higher bits using AND operator
if ( (cvWaitKey(10) & 255) == 27 ) break;
}
// Release the capture device housekeeping
cvReleaseCapture( &capture );
cvDestroyWindow( "Webcam" );
cvDestroyWindow( "Webcam2" );
return 0;
}
There is a neat function in OpenCV, called flip(). The C counterpart is named cvFlip(). And I am sure it will help you.
And I will also give you the advice I always give: Move from the C interface to C++! Much cleaner, much safer, much easier!
You can check this answer to see the differences between the two.

Unhandled exception in C++ using OpenCV libraries

I'm new to OpenCV and trying some stuff. I want to detect a hand using a webcam and here is a simple code. But it gives me something like that:
Unhandled exception at 0x000000013f5b140b in HaarCascade.exe: 0xC0000005: Access violation reading location 0x0000000000000004.
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
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);
}
Image:
http://i.imgur.com/Dneiw.png
Thank you for all your responses.
There's a chance that cvLoad() failed because it didn't found the file. That's a problem because you use it later on, and if it's a NULL pointer it can crash your application:
But you'll never know this unless you test the return of the function:
cascade = ( CvHaarClassifierCascade* )cvLoad( "haarcascade_hand.xml", 0, 0, 0 );
if (!cascade)
// Print something to say it failed!