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.
Related
I wrote this program by C++ using OpenCV to detect pedestrians.xml file that I have. The program should read all of the input images and display blue rectangles on the output images where pedestrians are located. But the code is giving me errors. Is there anyone who can tell me why these errors come?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include<iostream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
using namespace cv;
void detectAndDisplay( Mat frame );
/** Global variables */
String pedestrians_name = "hogcascade_pedestrians.xml";
//CascadeClassifier pedestrians;
string window_name = "Capture - pedestrians detection";
RNG rng(12345);
/** #function main */
int main( int argc, const char** argv )
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
//if( !pedestrians.load( pedestrians_name ) ){ printf("--(!)Error loading\n"); return -1; };
Mat image = imread("ped1.jpg");
Mat image_keypoints;
cvtColor(image, image_keypoints, CV_BGR2GRAY);
return 0;
}
/** #function detectAndDisplay */
void detectAndDisplay( Mat frame )
{
std::vector<Rect> pedestrians;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect faces
pedestrians.detectMultiScale( frame_gray, pedestrians, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size());
for( int i = 0; i < pedestrians.size(); i++ )
{
Point center( pedestrians[i].x + pedestrians[i].width*0.5, pedestrians[i].y + pedestrians[i].height*0.5 );
ellipse( frame, center, Size( pedestrians[i].width*0.5, pedestrians[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
Mat faceROI = frame_gray( pedestrians[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 );
}
these are the errors:
cascade.cpp: In function âvoid detectAndDisplay(cv::Mat)â:
cascade.cpp:46: error: âclass std::vector<cv::Rect_<int>, std::allocator<cv::Rect_<int> > >â has no member named âdetectMultiScaleâ
cascade.cpp:46: error: âCV_HAAR_SCALE_IMAGEâ was not declared in this scope
cascade.cpp:47: error: âCascadeClassifierâ has not been declared
cascade.cpp:47: error: invalid use of qualified-name â<declaration error>::detectMultiScaleâ
You need to add opencv_objdetect library. And include "opencv2/objdetect.hpp".
create a Cascade classifier object and load the xml file obj.load(xml file path)
First of all, in main() you never called detectAndDisplay() right? You need to call it if you want to execute it...
Second of all, you need to declare and load a cascade classifier in detectAndDisplay() before you use detectMultiScale.
CascadeClassifier pedestrians;
if( !pedestrians.load( pedestrians_name ) ){
printf("--(!)Error loading\n");
return;}
//.....
pedestrians.detectMultiScale( frame_gray, pedestrians, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
I am trying to implement Face detection viola jones classifier using opencv cascade. This is the code i am using:
int main( ){
SYSTEMTIME tm;
GetLocalTime(&tm);
printf("Date: %02d.%02d.%d, %02d:%02d:%02d:%02d\n", tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds);
//CString t = CTime::GetCurrentTime().Format("%H:%M:%S:%MS");
Mat image;
Mat frame_gray;
image = imread("test.jpg", CV_LOAD_IMAGE_COLOR);
namedWindow( "window1", 1 ); imshow( "window1", image );
// Load Face cascade (.xml file)
CascadeClassifier face_cascade;
face_cascade.load( "cascades.xml" );
cvtColor( image, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
GetLocalTime(&tm);
printf("Date: %02d.%02d.%d, %02d:%02d:%02d:%02d\n", tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds);
float pyramidScale = 1.5f;
// Detect faces
std::vector<Rect> faces;
face_cascade.detectMultiScale( frame_gray, faces, pyramidScale, 3, 0, Size(20, 20), Size(50, 50));
GetLocalTime(&tm);
printf("Date: %02d.%02d.%d, %02d:%02d:%02d:%02d\n", tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds);
// Draw circles on the detected faces
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( image, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 255, 255 ), 4, 8, 0 );
}
imshow( "Detected Face", image );
SYSTEMTIME tm1;
GetLocalTime(&tm);
printf("Date: %02d.%02d.%d, %02d:%02d:%02d:%02d\n", tm.wDay, tm.wMonth, tm.wYear, tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds);
//cout<< "Time : "<<tm.wHour<<":"<<tm.wMinute << ":"<< tm.wSecond << ":" << tm.wMilliseconds << "\n";
waitKey(0);
return 0;
}
The problem is it says this is viola jones implementation in opencv and usually takes 30fps to run (from the author side) but its taking 6 seconds to run a normal HD image for face detection of around 1920x1080. I wanted to ask is the implementation right or is there any problem with the way i am implementing the method and is there any way i can make it faster ? The cascade.xml is a file i trained using sample images. Thank you.
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!
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
);
}