#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#define PI 3.1415926
using namespace std;
using namespace cv;
void Palm_Carve(cv::Mat palm)
{
//cout<<1<<endl;
}//对已检测出的手掌进行下一步处理
/** Function Headers */
void Palm_Detect(Mat frame);
void RestoreVectors(vector<vector<Rect>>& vecs_bank, vector<Rect>& vecAll);
/** Global variables */
String palm_cascade_name = "myhaar.xml";
//String fist_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier palm_cascade;
string window_name = "Face 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; };
//-- 2. Read the video stream
capture = cvCaptureFromCAM(0);
if (capture)
{
while (true)
{
frame = cvQueryFrame(capture);
//-- 3. Apply the classifier to the frame
if (!frame.empty())
{
Palm_Detect(frame);
}
else
{
printf(" --(!) No captured frame -- Break!"); break;
}
int c = waitKey(1);
if ((char)c == 'q' || (char)c == 'Q' || 27 == c) { break; }
}
}
cvReleaseCapture(&capture);
return 0;
}
/** @function Palm_Detect */
void Palm_Detect(Mat frame)
{
std::vector<Rect> face;
static vector<vector<Rect>> Palm_stack;
const int MAX_NUM = 3;
Mat frame_gray;
cvtColor(frame, frame_gray, CV_BGR2GRAY);
//equalizeHist( frame_gray, frame_gray );
Size min, max;
min.width = 100;
min.height = 100;
max.width = 450;
max.width = 450;
//-- Palm detection
palm_cascade.detectMultiScale(frame_gray, face, 1.1, 3, 0, min, max);
Palm_stack.push_back(face);
if (Palm_stack.size() > MAX_NUM)
Palm_stack.erase(Palm_stack.begin());
vector<Rect> palmAll;
RestoreVectors(Palm_stack, palmAll);
groupRectangles(palmAll, 2);
Mat result(10, 10, CV_8UC3, cv::Scalar::all(1));
int i = 0;
for (size_t j = 0; j < palmAll.size(); j++)
{
//提取图像手的区域
Mat mask = Mat::zeros(frame.size(), CV_8UC1);
Rect rect;
rect.x = palmAll[j].x;
rect.width = palmAll[j].width;
if (palmAll[j].y <= 50)
{
rect.y = palmAll[j].y;
rect.height = palmAll[j].height;
}
else
{
rect.y = palmAll[j].y - 50;
rect.height = palmAll[j].height + 50;
}
//rectangle(frame, rect, Scalar(255,0,0), 1); //显示手掌方框
//设置矩形掩模
mask(rect).setTo(255);
result = frame(rect);
i = j + 1;
}
//cv::Canny(result,result,80,150);
//cv::imshow("result", result);
std::cout << "Palm Number :" << i << endl;
vector<Mat> channels;
imshow("result", result);
//取出手掌区域,下面写手掌分割的代码
//输入数据 Mat result/Y
Mat contours;
blur(result, result, Size(3, 3));
Canny(result, contours, 60, 120); //边缘检测
vector<cv::Vec2f> lines;
imshow("Canny", contours);
HoughLines(contours, lines, 1, 10 * PI / 180, 30);
vector<cv::Vec2f>::const_iterator iter = lines.begin();
cout << lines.size() << std::endl;
while (iter != lines.end())
{
float rho = (*iter)[0];
float theta = (*iter)[1];
if (theta<PI / 4. || theta>3.*PI / 4)
{ //画交点在上下两边的直线
Point pt1(rho / cos(theta), 0);
Point pt2((rho - result.rows*sin(theta)) / cos(theta), result.rows);
line(result, pt1, pt2, cv::Scalar(255), 2);
}
else
{ //画交点在左右两边的直线
Point pt1(0, rho / sin(theta));
Point pt2(result.cols, (rho - result.cols*cos(theta) / sin(theta)));
line(result, pt1, pt2, cv::Scalar(255), 2);
}
++iter;
}
//namedWindow ("hough");
imshow("hough", contours);
//Palm_Carve(result);
//手掌分割结束
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());
}
}