Beginner here. I'm trying to detect a circle and hand, and draw a circle around the circle and a rectangle around the hand, and display both in the same image. When I run the program I get some memory error, can anyone please help?
Below is my code:
#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);
}
The issue is that the size of the gray scale image created should be the same as that of the image obtained from camera.
Instead of:
IplImage *gray = cvCreateImage( cvSize(640,480), 8, 1 );
write it as:
IplImage *gray = cvCreateImage( cvSize(img->width,img->height), 8, 1);
From the error message it seems that you are reading elements of p[] that doesn't exist.
You should check that cvGetSeqElem() actually returns the number of elements you are expecting - it may be that the Hough routines isn't finding any.
I have the same error! You have to add to your code an if statement because when the camera starts cannot "see" any hand so the cvGetSeqElem get no values.
try this instead:
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
);
}
Related
I have recently started learning how to use OpenCV and i have been following the tutorials hosted by their website. I am using OpenCV 3.0, however, it seems some of the tutorial information is out of date.
I and on the tutorial "Cascade Classifier" link:
http://www.docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html
They provided example code is not running for me and I cannot understand why. I have provided the code example below:
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/** Function Headers */
void detectAndDisplay( Mat frame );
/** Global variables */
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);
/** #function main */
int main( int argc, const char** argv )
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
//-- 2. Read the video stream
capture = cvCaptureFromCAM( -1 );
if( capture )
{
while( true )
{
frame = cvQueryFrame( capture );
//-- 3. Apply the classifier to the frame
if( !frame.empty() )
{ detectAndDisplay( frame ); }
else
{ printf(" --(!) No captured frame -- Break!"); break; }
int c = waitKey(10);
if( (char)c == 'c' ) { break; }
}
}
return 0;
}
/** #function detectAndDisplay */
void detectAndDisplay( Mat frame )
{
std::vector<Rect> faces;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < faces.size(); i++ )
{
Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
Mat faceROI = frame_gray( faces[i] );
std::vector<Rect> eyes;
//-- In each face, detect eyes
eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t j = 0; j < eyes.size(); j++ )
{
Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
}
}
//-- Show what you got
imshow( window_name, frame );
}
The error for me arises on line 38 "frame = cvQueryFrame( capture );"
the "=" is underlined red and gives the error message displayed in the title of the question
I'm sorry if the code is not displayed correctly, this is my first time asking a question.
no fear, it's not exactly your fault, - you stumbled over outdated tutorial code, the arcane c-api is no more adequate today(and won't work with 3.0).
please replace :
CvCapture* capture;
capture = cvCaptureFromCAM( -1 );
if( capture )
{
with:
VideoCapture capture(-1);
if (capture.isOpened())
{
and:
frame = cvQueryFrame( capture );
with:
capture.read(frame);
also, opencv3.0 docs: http://docs.opencv.org/ref/master/
(your sample code is from 2.4.x)
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
I've been trying objectDetection in openCV..
Followed a few steps..
Resizing it to 64x64 resolution
Changing it to gray scale
Fetching XML for object detection
Drawing rectangle fringing the pattern
Yet, I couldn't achieve it..
Here's my code :
#include<iostream>
#include "cv.h"
#include "highgui.h"
#include<vector>
using namespace cv;
using namespace std;
int main()
{
IplImage* img;
img = cvLoadImage( "hindi3.jpg" );
vector<cv::Rect> objects;
// ***Resize image to 64x64 resolution***
IplImage *resizeImage = cvCreateImage(cvSize(64,64),8,3);
cvResize(img,resizeImage,CV_INTER_LINEAR);
cvShowImage("Resize",resizeImage);
cvWaitKey(0);
// ***Convert image to grayscale***
IplImage *grayImage = cvCreateImage(cvGetSize(resizeImage),8,1);
cvCvtColor(resizeImage,grayImage,CV_BGR2GRAY);
cvShowImage("gray",grayImage);
cvWaitKey(0);
// ***Getting the XML (Cascade xml generated thru haarTraining)***
CvMemStorage* storage = cvCreateMemStorage(0);
cout<<"Memory created\n";
cv::CascadeClassifier cascade;
cascade.load("cascade.xml");
//CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "cascade.xml" );
cout<<"cascade.xml loaded successfully\n";
double scale = 1.3;
static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}},
{{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}} };
// ***Detect objects***
cvClearMemStorage( storage );
objects.clear();
//CvSeq* objects = cvHaarDetectObjects( grayImage, cascade, storage, 1.1, 4, 0, cvSize( 40, 50 ));
//cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_DO_CANNY_PRUNING, cvSize(30, 30));
cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_SCALE_IMAGE, cvSize(30, 30));
// ***Draw a rectangle outside recognized pattern***
cout<<"Object size : "<<objects.size();
for( vector<cv::Rect>::const_iterator r = objects.begin(); r != objects.end(); r++)
{ //rectangle(img, *r, Scalar(0,0,255), 2, 8, 0);
cvRectangle( grayImage, cvPoint( r->x, r->y ), cvPoint( r->x + r->width, r->y + r->height ),Scalar(0,0,255));
cout<<"In the loop\n";
}
cvNamedWindow( "Output" );
cvShowImage( "Output", grayImage );
cvWaitKey(0);
cvReleaseImage(&resizeImage);
cvReleaseImage(&grayImage);
cvReleaseImage( &img );
return 0;
}
The object size printed by me shows 0 unfortunately :( Hence, it doesn't go to the for loop.. Can anyone help me out..
Thanks in advance
PS : I've commented some lines in the code which were not useful. Please lemme know if I can incorporate the same.
Found the answer..! I've missed out the specified arguments for detectMultiScale function.
It's working fine..Rectified code as follows
#include<iostream>
#include "cv.h"
#include "highgui.h"
#include<vector>
using namespace cv;
using namespace std;
int main()
{
IplImage* img;
img = cvLoadImage( "test.jpg" );
vector<cv::Rect> objects;
/*** Resizing is optional***
*****************************
IplImage *resizeImage = cvCreateImage(cvSize(64,64),8,3);
cvResize(img,resizeImage,CV_INTER_LINEAR);
cvShowImage("Resize",resizeImage);
cvWaitKey(0);*/
/*** Change image into grayscale***
**********************************/
IplImage *grayImage = cvCreateImage(cvGetSize(img),8,1);
cvCvtColor(img,grayImage,CV_BGR2GRAY);
//cvEqualizeHist(grayImage,grayImage); This is optional
cvShowImage("gray",grayImage);
cvWaitKey(0);
CvMemStorage* storage = cvCreateMemStorage(0);
cout<<"Memory created\n";
/*** Load the XML generated through haartraining***
**************************************************/
cv::CascadeClassifier cascade;
cascade.load("cascade.xml");
//CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "cascade.xml" );
cout<<"cascade.xml loaded successfully\n";
double scale = 1.3;
static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}},
{{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}} };
/*** Detect objects***
**********************/
cvClearMemStorage( storage );
objects.clear();
//CvSeq* objects = cvHaarDetectObjects( grayImage, cascade, storage, 1.1, 4, 0, cvSize( 40, 50 ));
//cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_DO_CANNY_PRUNING, cvSize(30, 30)); if captured through WebCam
cascade.detectMultiScale(grayImage, objects, 1.1, 3, CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING,cvSize(0,0), cvSize(100,100));
cout<<"Object size : "<<objects.size();
/***Draw Rectangle outside recognized pattern***
***********************************************/
for( vector<cv::Rect>::const_iterator r = objects.begin(); r != objects.end(); r++)
{ //rectangle(img, *r, Scalar(0,0,255), 2, 8, 0);
cvRectangle( grayImage, cvPoint( r->x, r->y ), cvPoint( r->x + r->width, r->y + r->height ),Scalar(0,0,255));
cout<<"In the loop\n";
}
cvNamedWindow( "Output" );
cvShowImage( "Output", grayImage );
cvWaitKey(0);
//cvReleaseImage(&resizeImage); If resized
cvReleaseImage(&grayImage);
cvReleaseImage( &img );
return 0;
}
And finally this worked..!
PS: This program holds good only when the input is taken through image unlike WebCam or Video.
I'm using OpenCV on a 64-bit Win 7, with VS2010 (C++).
I've tried so many source codes for detecting faces, they compile and run, but no detection takes place.
I'll give two examples:
1) In this first example, I'm using source code from:
http://www.bsd-noobz.com/opencv-guide/60-3-face-detection
I get the picture, but not the squares.
2) In this second example, I'm using code that I had downloaded some time ago (can't remember where from). This one shows the stream from the webcam, and again no detection is happening.
#include "stdafx.h"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
/** Function Headers */
void detectAndDisplay2( Mat frame );
/** Global variables */
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
//RNG rng(12345);
/** #function main */
int main()
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };
if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading eye cascade\n"); return -1; };
//-- 2. Read the video stream
capture = cvCaptureFromCAM( 1 );
if( capture )
{
while( true )
{
frame = cvQueryFrame( capture );
//-- 3. Apply the classifier to the frame
if( !frame.empty() )
{ detectAndDisplay2( frame ); }
else
{ printf(" --(!) No captured frame -- Break!"); break; }
int c = waitKey(10);
if( (char)c == 'c' ) { break; }
}
}
cvReleaseCapture(&capture);
cvDestroyWindow("Capture - Face detection");
return 0;
}
/** #function detectAndDisplay */
void detectAndDisplay2( Mat frame )
{
vector<Rect> faces;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( int i = 0; i < faces.size(); i++ )
{
Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
Mat faceROI = frame_gray( faces[i] );
vector<Rect> eyes;
//-- In each face, detect eyes
eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( int j = 0; j < eyes.size(); j++ )
{
Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
}
}
//-- Show what you got
imshow( "Processed", frame_gray );
imshow( "Capture - Face detection", frame );
}
I'd be really grateful if someone can help.
This is a opencv project in github. This error stems from two issues that I can see.
1) Make sure you’ve installed the correct OpenCV version. I suggest this install guide… It worked well for me.
2) Then, make sure you have added haarcascade_frontalface_alt.xml to inside of the executable file – which should be in a folder like ../build/bin/haarcascade_frontalface_alt.xml when you built the project).
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!