参考: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 <iostream>
#include <string>
#include <opencv2\opencv.hpp>
#include <stdio.h>
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 <Mat> 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而非RGBsplit(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 < frame.rows; i++){for (int j = 0; j < frame.cols;j++){int r,g,b;r = frame.at<cv::Vec3b>(i,j)[2];g = frame.at<cv::Vec3b>(i,j)[1];b = frame.at<cv::Vec3b>(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<cv::Vec3b>(i,j) = Vec3b(255, 255, 255);}else if( r>220 && g>210 &&b>170 && abs(r-g)<=15 && r>b && g<b){tempresult.at<cv::Vec3b>(i,j) = Vec3b(255, 255, 255);}}};RIOresult = tempresult.clone();frame.copyTo(RIOframe, tempresult);
};//椭圆模型
void hand_YCbCr_ellipse()
{/*椭圆皮肤模型*/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 < frame.rows; i++){for (int j = 0; j < frame.cols;j++){int y, cr, cb;y = frameYCrCb.at<cv::Vec3b>(i,j)[0];cr = frameYCrCb.at<cv::Vec3b>(i,j)[1];cb = frameYCrCb.at<cv::Vec3b>(i,j)[2];if( skinCrCbHist.at<uchar>(cr,cb) >0 ){tempresult.at<cv::Vec3b>(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<Mat> 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 -> IplImageCvAdaptiveSkinDetector 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 framecvCopy(frame1, skinImg, maskImg);Mat tmp(skinImg);  //IplImage -> MatRIOresult= tmp.clone();cvReleaseImage(&skinImg);cvReleaseImage(&maskImg);frame.copyTo(RIOframe, RIOresult);
};

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

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

    6种肤色检测方法的原理及实现(opencv, C++) Mr Qin 分类:机器视觉 个人专栏:图像处理 发布时间 2021.06.18 阅读数 2024 评论数 0 0 简介: 本博文首发csdn链 ...

  2. Opencv暑期历程--Day10(6种肤色检测方法,YCrCb肤色模型解释,再理解一遍掩模)

    从一篇文章了解到,肤色检测主要有以下七种方法: RGB color space Ycrcb之cr分量+otsu阈值化 YCrCb中133<=Cr<=173 77<=Cb<=12 ...

  3. 随机性测试软件,5种随机性检测方法

    <5种随机性检测方法>由会员分享,可在线阅读,更多相关<5种随机性检测方法(15页珍藏版)>请在人人文库网上搜索. 1.采用,Maurer,通用统计检测等,方法来实现随机性检测 ...

  4. OpenCV-Python实战(14)——人脸检测详解(仅需6行代码学会4种人脸检测方法)

    OpenCV-Python实战(14)--人脸检测详解(仅需6行代码学会4种人脸检测方法) 0. 前言 1. 人脸处理简介 2. 安装人脸处理相关库 2.1 安装 dlib 2.2 安装 face_r ...

  5. 14种异常检测方法总结

    作者丨Ai 来源丨宅码 编辑丨极市平台 本文收集整理了公开网络上一些常见的异常检测方法(附资料来源和代码).不足之处,还望批评指正. 一.基于分布的方法 1. 3sigma 基于正态分布,3sigma ...

  6. 14种异常检测方法汇总

    今天给大家分享一篇关于异常检测的文章,重点介绍了14种公开网络上一些常见的异常检测方法(附资料来源和代码). 一.基于分布的方法 1. 3sigma 基于正态分布,3sigma准则认为超过3sigma ...

  7. 14种异常检测方法汇总(附代码)!

    公众号:尤而小屋 作者:Ai 编辑:Peter 今天给大家分享一篇关于异常检测的文章,重点介绍了14种公开网络上一些常见的异常检测方法(附资料来源和代码). 一.基于分布的方法 1. 3sigma 基 ...

  8. 14种异常检测方法理论和代码总结

    作者丨Ai 来源丨宅码 编辑丨极市平台 导读 本文收集整理了公开网络上一些常见的异常检测方法(附资料来源和代码). 本文收集整理了公开网络上一些常见的异常检测方法(附资料来源和代码).不足之处,还望批 ...

  9. One_hot和Word2Vec两种词向量方法的原理及比较

    对于文本处理,首要的任务是要对非结构化数据进行结构化处理,由此诞生了词向量表示的方法,再众多词向量表示方法中,尤其以One_hot和word2vec两种方法最常用,下面也针对这俩方法进行阐述 One_ ...

最新文章

  1. ehchache验证缓存过期的api_ASP.NET Core ResponseCache进行缓存操作
  2. android sdk启动不了,windows server 2008下android sdk不能正常启动
  3. 力扣(LeetCode)打卡刷题交流计划(长期维护)
  4. Sqoop(四)增量导入、全量导入、减量导入
  5. Ext.Net ASP.NET
  6. 关于容量设计、规划、治理 你知多少?
  7. 最新微信公众平台JS逆向分析
  8. 1 阿里云Nginx配置https实现域名访问项目
  9. 【HDOJ2087】剪花布条(KMP)
  10. [转载] PyTorch: 序列到序列模型(Seq2Seq)实现机器翻译实战
  11. JavaScript:对象转换为字符串、字符串转换为对象
  12. Codeforces123E. Maze【树形dp】【概率dp】【证明题】
  13. 修正 Mui 下拉上拉刷新功能
  14. ZOJ 3256 Tour in the Castle(插头DP-按行递推—矩阵)
  15. java——编程案例
  16. 2022年天猫618超级红包玩法入口
  17. r语言 rgl 强制过程中_R语言中%||%是什么意思?
  18. sleuth feign instrument 分析
  19. python函数def无效_python自定义函数def的应用详解
  20. python实现K-means多维数据聚类代码

热门文章

  1. 干货 | 如何用好 ISO 9001质量管理体系
  2. JAVA 字母+数字混合自增(适用组织机构新、流水号等生成)
  3. stata行业变量怎么赋值_动态面板模型估计方法简介以及stata应用
  4. bootstrap以列表展示数据并实现CRUD
  5. 【一本通】1218:取石子游戏(博弈论)
  6. 蓝桥杯 历届真题 古堡算式【省赛】【本科组】
  7. 解决mysql导出Excel中文乱码问题
  8. itext html转换pdf,itext转换html成pdf(支持中文、图片)
  9. 【Azure Data Platform】ETL工具(11)——ADF 数据流
  10. [19保研]西北工业大学 计算机学院 2018年全国优秀大学生暑期夏令营招生简章