基于人脸检测的肤色采集以及两种常见肤色模型建模
2015-05-21 15:35
399 查看
[code]#include "relativeFunction.h" int main() { //svmTest(); //neuralTest(); char imageFileDir[100]; CascadeClassifier cc; cc.load("haarcascade_frontalface_alt2.xml"); VideoCapture cap(0); Mat frame; int countOfCheckFace = 0; vector<Mat> skinRegion; /***************************利用人脸检测收集可能的肤色像素********************************/ while(1) { cap >> frame; blur(frame,frame,Size(5,5)); resize(frame,frame,Size(640,480)); Mat gray; cvtColor(frame,gray,CV_BGR2GRAY); vector<Rect> objects; cc.detectMultiScale(gray, objects, 1.1, 3, 0); Mat newImage; if(!objects.empty() && objects[0].width > 100 && objects[0].height > 100) { //Mat white(gray.size(),CV_8UC3,Scalar::all(255)); Mat white = Mat::zeros(frame.size(),CV_8UC3); if(objects.size() == 1) { rectangle(white,objects[0],Scalar(0,0,255)); if(countOfCheckFace >= 20) { break; } else countOfCheckFace++; ; } else continue; int width = objects[0].width/8; int height = objects[0].height/8; Rect rr = Rect(objects[0].x+width,objects[0].y+2*height,6*width, 4*height); rectangle(white,rr,Scalar(255,0,255)); Mat newImage = frame(objects[0]); Mat ycc; cvtColor(newImage,ycc,CV_BGR2YCrCb); Mat a[3]; split(ycc,a); skinRegion.push_back(ycc); Mat mask; threshold(a[1],mask,131,255,THRESH_BINARY); imshow("dst",mask); Mat mmask; mask.convertTo(mmask,CV_8UC1,255,0); Mat roi = Mat::zeros(newImage.size(),CV_8UC3); newImage.copyTo(roi,mmask); sprintf(imageFileDir,"skin\\image%d.jpg",time(0)); imwrite(imageFileDir, roi); imshow("roi",roi); char context[100]; sprintf(context,"%s","this is fist"); putText(white,context,Point(50,50),FONT_HERSHEY_COMPLEX,1.0,Scalar(0,0,0)); imshow("white", white); } waitKey(22); } resize(frame,frame,Size(320,240)); float mu = 0; float sigma = 0; vector<float> cr; vector<float> cb; int n = skinRegion.size(); Mat tuoyuan = Mat(255,255,CV_8UC3,Scalar::all(255)); vector<Point> fitEllipsePointSet; for(int i = 0; i < n; i++) { int imageRow = skinRegion[i].rows; int imageCol = skinRegion[i].cols; //cout << imageRow << "\t" << imageCol << endl; for(int ii = 0; ii < imageRow; ii = ii + 10) { for(int jj = 0; jj < imageCol; jj = jj + 10) { Vec3b ycrcb = skinRegion[i].at<Vec3b>(ii,jj); //cout << ii << "\t" << jj << endl; if(ycrcb[1] > 125) { cr.push_back(ycrcb[1]); cb.push_back(ycrcb[2]); fitEllipsePointSet.push_back(Point(ycrcb[1],ycrcb[2])); circle(tuoyuan,Point(ycrcb[1],ycrcb[2]),1,Scalar(255,0,0)); } } } } /**************************椭圆肤色模型*********************************/ RotatedRect ellipse1 = fitEllipse(fitEllipsePointSet); ellipse(tuoyuan,ellipse1.center,ellipse1.size - Size2f(0,0),ellipse1.angle,0,360,Scalar(0,0,255),-1); Mat tyModel(frame.size(),CV_8UC1,Scalar::all(0)); ellipse(tyModel,ellipse1.center,ellipse1.size - Size2f(0,0),ellipse1.angle,0,360,Scalar(255,255,255),-1); for(int i = 0; i < 255; i = i + 20) { line(tuoyuan,Point(0,i+20),Point(255,i+20),Scalar(0,0,0)); line(tuoyuan,Point(i+20,0),Point(i+20,255),Scalar(0,0,0)); } time_t t = time(NULL); struct tm* tm = localtime(&t); char fileDate[100]; sprintf(fileDate,"%d:%d:%d:%d:%d",1900+tm->tm_year,1+tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min); putText(tuoyuan,fileDate,Point(5,50),FONT_HERSHEY_COMPLEX,1.0,Scalar(0,0,255)); sprintf(imageFileDir,"fusejulei\\image%d.jpg",time(0)); imwrite(imageFileDir,tuoyuan); imshow("tuoyuan", tuoyuan); imshow("tyModel", tyModel); while(1) { cap >> frame; Mat ycc; cvtColor(frame,ycc,CV_BGR2YCrCb); Mat hh(frame.size(),CV_8UC1); for(int i = 0; i < 480; i++) { for(int j = 0; j < 640; j++) { Vec3b pixel = ycc.at<Vec3b>(i,j); if(tyModel.at<uchar>(pixel[1],pixel[2]) > 0) { hh.at<uchar>(i,j) = 0; } else { hh.at<uchar>(i,j) = 255; } } } Mat kernel; kernel = getStructuringElement(MORPH_RECT,Size(5,5)); erode(hh,hh,kernel); dilate(hh,hh,kernel); dilate(hh,hh,kernel); erode(hh,hh,kernel); Mat contour_image = Mat(frame.size(),CV_8UC3,Scalar::all(255)); vector<vector<Point>> contour; vector<Vec4i> heri; findContours(hh,contour,heri,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE); drawContours(contour_image,contour,-1,Scalar(255,0,255)); imshow("contour", contour_image); imshow("hh",hh); waitKey(22); } /***************************************下面是高斯肤色模型*******************************************/ Scalar avr; Scalar stddev; meanStdDev(cr,avr,stddev); mu = avr[0]; sigma = stddev[0]; cout << avr << "\t" << stddev << endl; cout << skinRegion.size(); //system("pause"); while(1) { cap >> frame; Mat ycrcb; cvtColor(frame,ycrcb,CV_BGR2YCrCb); Mat aa[3]; split(ycrcb,aa); Mat res(aa[1].size(),CV_32FC1); cout << frame.size() << endl; //system("pause"); for(int i = 0; i < res.rows; i++) { for(int j = 0; j < res.cols; j++) { res.at<float>(i,j) = exp(-(aa[1].at<char>(i,j)-mu)*(aa[1].at<char>(i,j)-mu)/(2*sigma*sigma)); //cout << "mu = " << mu << "\t" << "sigma = " << sigma << endl; //cout << i << "\t" << j << endl; } } Mat dstt = Mat::zeros(res.size(),CV_32FC1); double max1 = 0; double min1 = 0; Mat hh = res.clone(); minMaxIdx(hh, &min1, &max1,0,0,Mat()); cout << min1 << "\t" << max1 << endl; for(int i = 0; i < 480; i++) { for(int j = 0; j < 640; j++) { /*dstt.at<float>(j,i) = 255*(res.at<float>(j,i) - min1) /(max1 - min1);*/ //cout << i << "\t" << j << endl; if(res.at<float>(i,j) > 0.35) dstt.at<float>(i,j) = 255; else dstt.at<float>(i,j) = 0; } } imshow("dstt",dstt); Mat thresh; threshold(aa[1],thresh,135,255.0,THRESH_BINARY); imshow("thresh",thresh); waitKey(22); } system("pause"); return 0; }
相关文章推荐
- 人脸--基于肤色模型的人脸检测研究
- 【转】简单的基于YCrCb颜色空间的人脸检测(肤色)
- 基于肤色和眼睛定位的人脸检测算法——MATLAB实现【转】
- 肤色检测算法 - 基于二次多项式混合模型的肤色检测。
- 肤色检测算法 - 基于二次多项式混合模型的肤色检测。
- 简单的基于YCrCb颜色空间的人脸检测(肤色)
- 人脸检测---基于肤色检测的实现
- 基于肤色分割和改进AdaBoost 算法的人脸检测
- 基于肤色和眼睛定位的人脸检测算法——MATLAB实现
- 简单的基于YCrCb颜色空间的人脸检测(肤色)
- Python基于YCbCr 肤色模型的情色图片检测的简单实现
- 简单的基于YCrCb颜色空间的人脸检测(肤色)
- 基于caffenet网络人脸检测模型的测试步骤
- 基于反向投影的肤色学习以及手势模型建立
- 基于肤色的人脸检测
- 肤色检测算法 - 基于二次多项式混合模型的肤色检测。
- 肤色检测算法 - 基于二次多项式混合模型的肤色检测。
- 基于肤色的人脸检测与分割
- opencv椭圆肤色模型人脸检测
- 肤色检测算法 - 基于二次多项式混合模型的肤色检测