思路:利用训练好的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(palms_bank, palmAll);
groupRectangles(palmAll, 2);
for( size_t j = 0; j < palmAll.size(); j++ )
{
rectangle(frame, palmAll[j], Scalar(0,255,0), 2);
}
//-- Fist detection
fist_cascade.detectMultiScale( frame_gray, fists, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
fists_bank.push_back(fists);
if(fists_bank.size() > MAX_NUM)
fists_bank.erase(fists_bank.begin());
vector<Rect> fistAll;
RestoreVectors(fists_bank, fistAll);
groupRectangles(fistAll, 2);
for( size_t j = 0; j < fistAll.size(); j++ )
{
rectangle(frame, fistAll[j], Scalar(0,0,255), 2);
}
//-- Show what you got
imshow( window_name, frame );
}
void RestoreVectors(vector<vector<Rect>>& vecs_bank, vector<Rect>& vecAll)
{
for(size_t i = 0; i < vecs_bank.size(); i++){
vecAll.insert(vecAll.end(), vecs_bank[i].begin(), vecs_bank[i].end());
}
}
参考:
groupRectangles
Groups the object candidate rectangles.
- **C++:**voidgroupRectangles(vector
& **rectList**, int **groupThreshold**, double **eps**=0.2)
- **C++:**voidgroupRectangles(vector
& **rectList**, vector & **weights**, int**groupThreshold**, double **eps**=0.2)
- **Python:**cv2.groupRectangles(rectList, groupThreshold[, eps])→ rectList, weights
-
Parameters: * **rectList** – Input/output vector of rectangles. Output vector includes retained and grouped rectangles. (The Python list is not modified in place.)
* **groupThreshold** – Minimum possible number of rectangles minus 1. The threshold is used in a group of rectangles to retain it.
* **eps** – Relative difference between sides of the rectangles to merge them into a group.
The function is a wrapper for the generic function partition() . It clusters all the input rectangles using the rectangle equivalence criteria that combines rectangles with similar sizes and similar locations. The similarity is defined byeps. Wheneps=0, no clustering is done at all. If , all the rectangles are put in one cluster. Then, the small clusters containing less than or equal togroupThresholdrectangles are rejected. In each other cluster, the average rectangle is computed and put into the output rectangle list.
原文:http://blog.csdn.net/lichengyu/article/details/38544189
原文链接: https://www.cnblogs.com/lxy2017/p/4044392.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/150514
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!