6种肤色检测方法的原理及实现(C++) 您所在的位置:网站首页 python肤色检测 6种肤色检测方法的原理及实现(C++)

6种肤色检测方法的原理及实现(C++)

2024-07-01 19:02| 来源: 网络整理| 查看: 265

参考:https://blog.csdn.net/qq_22527639/article/details/81501565

6种肤色检测算法实现 简介:原理介绍:代码实现(C++):

简介:

肤色分割的原理就是在不同的颜色区间进行颜色分割,内容都大致相同,包括 (1) 基于HSV颜色空间的阈值肤色识别 (2) 基于RGB颜色空间的阈值肤色识别 (3) 基于YCbCr颜色空间的阈值肤色识别 (4) 基于YCbCr颜色空间和椭圆皮肤模型的皮肤识别 (5) 基于YCbCr颜色空间的Otsu阈值肤色识别 (6)OPencv自带的函数

原理介绍:

在这里插入图片描述

各种肤色检测效果: 在这里插入图片描述

代码实现(C++):

(参数比模型重要的多 orz)

#include #include #include #include using namespace cv; using namespace std; //-----各颜色空间的参数-------------------------------------// int minH = 2, maxH = 13;//肤色分割阈值白天建议3 14 int minR = 95, minG = 40, minB = 20, max_min = 15, absR_G= 10; int minCr = 138, maxCr = 243, minCb = 77, maxCb = 127; int ecl_x = 113, ecl_y = 156, leng_x = 24, leng_y = 23, ang =43; Mat frame, frameH, frameHSV, frameYCrCb; //不同颜色空间下的图片 Mat RIOframe, RIOresult; //二值化得到的图像,识别出的皮肤区域,最终结果,将结果显示在原图 vector RGBchannels, HSVchannels; //RGB通道分离,HSV通道分离 //-----6种肤色识别方法-------------------------------------// void hand_HSV(); void hand_RGB(); void hand_YCbCr_ellipse();//椭圆模型 void hand_YCbCr(); void hand_YCbCr_Otsu(); void hand_opencv(); int main() { while (true) { frame = imread("test.jpg"); resize(frame, frame, Size(frame.cols*0.1, frame.rows*0.1));//降采样 namedWindow("原始图片", CV_WINDOW_NORMAL); imshow("原始图片",frame); //--------------------------6种肤色检测方法------------------------------------// //hand_HSV(); //hand_RGB(); hand_YCbCr_ellipse();//椭圆模型 //hand_YCbCr(); //hand_YCbCr_Otsu(); //hand_opencv(); namedWindow("肤色分割之后的图片", CV_WINDOW_NORMAL); imshow("肤色分割之后的图片", RIOframe);// 显示肤色分割之后的图片 RIOframe.setTo(0); waitKey(1); } system("pause"); return 0; } //-----6种肤色识别方法-------------------------------------// void hand_HSV() { cvtColor(frame, frameHSV, CV_BGR2HSV);//在opencv中,其默认的颜色制式排列是BGR而非RGB split(frameHSV, HSVchannels);//分离后, channels[0]对应H, channels[1]对应S, channels[2]对应 frameH = HSVchannels[0]; inRange(frameH, Scalar(minH), Scalar(maxH), RIOresult); frame.copyTo(RIOframe, RIOresult); }; void hand_RGB() { //imshow("4.肤色分割之后的图片", frame); Mat tempresult = Mat(frame.rows, frame.cols, CV_8UC3, Scalar(0)); for (int i = 0; i int r,g,b; r = frame.at(i,j)[2]; g = frame.at(i,j)[1]; b = frame.at(i,j)[0]; if( r>minR && g>minG && b>minB && max(max (r,g),b) - min(min (r,g),b)> max_min && abs(r-g)>absR_G && r>g && r>b) //if( r>95 && g>40 && b>20 && max(max (r,g),b) - min(min (r,g),b)> 15 && abs(r-g)>15 && r>g && r>b ) { tempresult.at(i,j) = Vec3b(255, 255, 255); } else if( r>220 && g>210 &&b>170 && abs(r-g)b && g /*椭圆皮肤模型*/ Mat skinCrCbHist = Mat::zeros(Size(256, 256), CV_8UC1); //ellipse(skinCrCbHist, Point(113, 155.6), Size(23.4, 23.2), 43.0, 0.0, 360.0, Scalar(255, 255, 255), -1); ellipse(skinCrCbHist, Point(ecl_x, ecl_y), Size(leng_x, leng_y), ang, 0.0, 360.0, Scalar(255, 255, 255), -1); cvtColor(frame, frameYCrCb , CV_BGR2YCrCb); Mat tempresult = Mat(frame.rows, frame.cols, CV_8UC3, Scalar(0)); for (int i = 0; i int y, cr, cb; y = frameYCrCb.at(i,j)[0]; cr = frameYCrCb.at(i,j)[1]; cb = frameYCrCb.at(i,j)[2]; if( skinCrCbHist.at(cr,cb) >0 ) { tempresult.at(i,j) = Vec3b(255, 255, 255); } } }; RIOresult = tempresult.clone(); frame.copyTo(RIOframe, tempresult); }; void hand_YCbCr() { cvtColor(frame, frameYCrCb , CV_BGR2YCrCb); Mat tempresult = Mat(frame.rows, frame.cols, CV_8UC3, Scalar(0)); inRange(frameYCrCb, Scalar(0,minCr,minCb), Scalar(255, maxCr, maxCb), RIOresult); frame.copyTo(RIOframe, RIOresult); }; void hand_YCbCr_Otsu() { cvtColor(frame, frameYCrCb , CV_BGR2YCrCb); Mat tempresult = Mat(frame.rows, frame.cols, CV_8UC3, Scalar(0)); Mat detect; vector channels; split(frameYCrCb, channels); RIOresult = channels[1]; threshold(RIOresult, RIOresult, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); frame.copyTo(RIOframe, RIOresult); }; void hand_opencv() { IplImage *frame1; frame1 = &IplImage(frame); //Mat -> IplImage CvAdaptiveSkinDetector filter(1, CvAdaptiveSkinDetector::MORPHING_METHOD_ERODE_DILATE); IplImage *maskImg = cvCreateImage(cvSize(frame.cols, frame.rows), IPL_DEPTH_8U, 1); IplImage *skinImg = cvCreateImage(cvSize(frame.cols, frame.rows), IPL_DEPTH_8U, 3); cvZero(skinImg); filter.process(frame1, maskImg); // process the frame cvCopy(frame1, skinImg, maskImg); Mat tmp(skinImg); //IplImage -> Mat RIOresult= tmp.clone(); cvReleaseImage(&skinImg); cvReleaseImage(&maskImg); frame.copyTo(RIOframe, RIOresult); };


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有