思路:利用训练好的palm.xml和fist.xml文件,用OpenCV的CascadeClassifier对每一帧图像检测palm和fist,之后对多帧中检测到的palm和fist进行聚类分组,满足分组条件的区域为最终检测结果。
代码:
#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 );
void RestoreVectors(vector<vector<Rect>>& vecs_bank, vector<Rect>& vecAll);
/** Global variables */
String palm_cascade_name = "palm.xml";
String fist_cascade_name = "fist.xml";
CascadeClassifier palm_cascade;
CascadeClassifier fist_cascade;
string window_name = "Capture - Palm and fist detection";
/** @function main */
int main( int argc, const char** argv )
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
if( !palm_cascade.load( palm_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
if( !fist_cascade.load( fist_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 == 'q' || (char)c == 'Q' || 27 == c) { break; }
}
}
cvReleaseCapture(&capture);
return 0;
}
/** @function detectAndDisplay */
void detectAndDisplay( Mat frame )
{
std::vector<Rect> faces;
std::vector<Rect> palms;
std::vector<Rect> fists;
static vector<vector<Rect>> palms_bank;
static vector<vector<Rect>> fists_bank;
const int MAX_NUM = 3;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Palm detection
palm_cascade.detectMultiScale( frame_gray, palms, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
palms_bank.push_back(palms);
if(palms_bank.size() > MAX_NUM)
palms_bank.erase(palms_bank.begin());
vector<Rect> palmAll;
RestoreVectors(palm