一、RGB color space

检测代码如下:

void SkinRGB(IplImage* src,IplImage* dst)
{
//RGB颜色空间
//均匀照明:R>95,G>40,B>20,R-B>15,R-G>15,R>B%R
//侧向照明:R>200,G>210,B>170,R-B<=15,R>B,G>B int height = src->height, width = src->width, channel = src->nChannels, step = src->widthStep;
int b = , g = , r = ; cvZero(dst);
unsigned char* p_src = (unsigned char*)src->imageData;
unsigned char* p_dst = (unsigned char*)dst->imageData; for(int j = ; j < height; j++){
for(int i = ; i < width; i++){
if((p_src[j*step+i*channel+r] > 95 && p_src[j*step+i*channel+g] > 40 && p_src[j*step+i*channel+b] > 20 &&
(p_src[j*step+i*channel+r] - p_src[j*step+i*channel+b]) > 15 && (p_src[j*step+i*channel+r] - p_src[j*step+i*channel+g]) > ) ||
(p_src[j*step+i*channel+r] > 200 && p_src[j*step+i*channel+g] > 210 && p_src[j*step+i*channel+b] > 170 &&
(p_src[j*step+i*channel+r] - p_src[j*step+i*channel+b]) <= 15 && p_src[j*step+i*channel+r] > p_src[j*step+i*channel+b] &&
p_src[j*step+i*channel+g] > p_src[j*step+i*channel+b]))
p_dst[j*width+i]=;
}
}
}

二、二次多项式模式检测(RG color space)

void cvSkinRG(IplImage* rgb,IplImage* gray)
{
assert(rgb->nChannels==&&gray->nChannels==); const int R=;
const int G=;
const int B=; double Aup=-1.8423;
double Bup=1.5294;
double Cup=0.0422;
double Adown=-0.7279;
double Bdown=0.6066;
double Cdown=0.1766;

for (int h=;h<rgb->height;h++) {
unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;
unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;
for (int w=;w<rgb->width;w++){
int s=pRGB[R]+pRGB[G]+pRGB[B];
double r=(double)pRGB[R]/s;
double g=(double)pRGB[G]/s;
double Gup=Aup*r*r+Bup*r+Cup;
double Gdown=Adown*r*r+Bdown*r+Cdown;
double Wr=(r-0.33)*(r-0.33)+(g-0.33)*(g-0.33);
if (g<Gup && g>Gdown && Wr>0.004){
*pGray=;
}
else{
*pGray=;
}
pGray++;
pRGB+=;
}
}
}

三、Ycrcb之cr分量+otsu阈值化

原理:       a.将RGB图像转换到YCrCb颜色空间,提取Cr分量图像

b.对Cr做自适应二值化处理(Ostu法)

void cvSkinOtsu(IplImage* src, IplImage* dst)
{
//Cr自适应阈值法
// IplImage* img_ycrcb=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,);
IplImage* img_cr=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,); cvCvtColor(src,img_ycrcb,CV_BGR2YCrCb);
cvSplit(img_ycrcb,,img_cr,,);
cvThresholdOtsu(img_cr,img_cr);
cvCopy(img_cr,dst); cvReleaseImage(&img_ycrcb);
cvReleaseImage(&img_cr);
} void cvThresholdOtsu(IplImage* src, IplImage* dst)
{
int height=src->height,width=src->width,threshold=;
double histogram[]={};
double average=0.0,max_variance=0.0,w=0.0,u=0.0;
IplImage* temp=cvCreateImage(cvGetSize(src),src->depth,);
if(src->nChannels!=)cvCvtColor(src,temp,CV_BGR2GRAY);
else cvCopy(src,temp); unsigned char* p_temp=(unsigned char*)temp->imageData; //计算灰度直方图
//
for(int j=;j<height;j++) {
for(int i=;i<width;i++) {
histogram[p_temp[j*width+i]]++;
}
}
for(int i=;i<;i++)histogram[i]=histogram[i]/(double)(height*width); //计算平局值
for(int i=;i<;i++)average+=i*histogram[i]; for(int i=;i<;i++) {
w+=histogram[i];
u+=i*histogram[i]; double t=average*w-u;
double variance=t*t/(w*(-w));
if(variance>max_variance) {
max_variance=variance;
threshold=i;
}
}
cvThreshold(temp,dst,threshold,,CV_THRESH_BINARY); cvReleaseImage(&temp);
}

四、OpenCV自带肤色检测类——CvAdaptiveSkinDetector

通过颜色阈值分割肤色部分,皮肤检测算法是在HSV空间进行。流程如下:

//构造函数
CvAdaptiveSkinDetector(int samplingDivider = , int morphingMethod = MORPHING_METHOD_NONE); /*
参数1:样本采样的间隔,默认情况下为1,即表示不进行降采样
参数2:图形学操作方式,即对用皮肤检测后的图像进行图形学操作。其取值有3种可能——MORPHING_METHOD_ERODE(只进行一次腐蚀操作);MORPHING_METHOD_ERODE_ERODE(连续进行2次腐蚀操作);MORPHING_METHOD_ERODE_DILATE(先进行一次腐蚀操作,后进行一次膨胀操作)
*/
virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);

/*
参数1:需要进行皮肤检测的输入图像
参数2:输出皮肤的掩膜图像——值为1代表该像素为皮肤,值为0代表非皮肤。
*/

PS:这个函数只有opencv的c版本的,因为CvAdaptiveSkinDetector这个类放在opencv源码里的contrib目录里,即表示比较新的但不成熟的算法。

#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <contrib\contrib.hpp>
#include <core\core.hpp>
#include <imgproc\imgproc.hpp>
#include<time.h> int main()
{
CvCapture* capture=cvCreateCameraCapture();
cvNamedWindow("Input Video",);
cvNamedWindow("Output Video",); IplImage* img_src=NULL;
IplImage* input_img=NULL;
IplImage* output_mask=NULL;
IplImage* output_img=NULL; clock_t start,finish;
double duration; CvAdaptiveSkinDetector skin_detector(,CvAdaptiveSkinDetector::MORPHING_METHOD_ERODE_DILATE); //定义肤色检测算子 while()
{
img_src=cvQueryFrame(capture);
if(!img_src) break;
cvShowImage("Input Video",img_src);
if(input_img==NULL){
input_img=cvCreateImage(cvGetSize(img_src),img_src->depth,img_src->nChannels);
}
cvCopy(img_src,input_img); output_img=cvCreateImage(cvGetSize(img_src),img_src->depth,img_src->nChannels);
cvZero(output_img); if(output_mask==NULL){
output_mask=cvCreateImage(cvGetSize(img_src),img_src->depth,);
} //肤色检测
//
start=clock();
skin_detector.process(input_img,output_mask);
finish=clock();
duration=(double)(finish-start)/CLOCKS_PER_SEC;
printf("elapsed time :%.0f 毫秒\n",duration*); cvCopy(img_src,output_img,output_mask);
cvShowImage("Output Video",output_img); char c=cvWaitKey();
if(c==)break;
} cvReleaseCapture(&capture);
cvDestroyWindow("Video");
}

五、HSV检测

void cvSkinHSV(IplImage* src,IplImage* dst)
{
IplImage* hsv=cvCreateImage(cvGetSize(src),,);
//IplImage* cr=cvCreateImage(cvGetSize(src),8,1);
//IplImage* cb=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,hsv,CV_BGR2HSV);
//cvSplit(ycrcb,0,cr,cb,0); static const int V=;
static const int S=;
static const int H=; //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);
cvZero(dst); for (int h=;h<src->height;h++) {
unsigned char* phsv=(unsigned char*)hsv->imageData+h*hsv->widthStep;
unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;
unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;
for (int w=;w<src->width;w++) {
if (phsv[H]>=&&phsv[H]<=)
{
memcpy(pdst,psrc,);
}
phsv+=;
psrc+=;
pdst+=;
}
}
//cvCopyImage(dst,_dst);
//cvReleaseImage(&dst);
}

OpenCV——肤色检测的更多相关文章

  1. Python人体肤色检测

    代码地址如下:http://www.demodashi.com/demo/12967.html Python人体肤色检测 概述 本文中的人体肤色检测功能采用 OpenCV 库实现, OpenCV是一个 ...

  2. Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结

    Atitit 图像处理--图像分类 模式识别 肤色检测识别原理 与attilax的实践总结 1.1. 五中滤镜的分别效果..1 1.2. 基于肤色的图片分类1 1.3. 性能提升2 1.4. --co ...

  3. opencv直线检测在c#、Android和ios下的实现方法

    opencv直线检测在c#.Android和ios下的实现方法 本文为作者原创,未经允许,不得转载 :原文由作者发表在博客园:http://www.cnblogs.com/panxiaochun/p/ ...

  4. OpenCv皮肤检测-HSV分离

    HSV皮肤检测 // 进行肤色检测 void SkinDetect(IplImage* src, IplImage* dst) { // 创建图像头 IplImage* hsv = cvCreateI ...

  5. OPENCV条形码检测与识别

    条形码是当前超市和部分工厂使用比较普遍的物品,产品标识技术,使用摄像头检测一张图片的条形码包含有两个步骤,第一是定位条形码的位置,定位之后剪切出条形码,并且识别出条形码对应的字符串,然后就可以调用网络 ...

  6. SSE图像算法优化系列十:简单的一个肤色检测算法的SSE优化。

    在很多场合需要高效率的肤色检测代码,本人常用的一个C++版本的代码如下所示: void IM_GetRoughSkinRegion(unsigned char *Src, unsigned char ...

  7. OpenCV矩形检测

    OpenCV矩形检测 需求:提取图像中的矩形,图像存在污染现象,即矩形区域不是完全规则的矩形. 思路一:轮廓法 OpenCV里提取目标轮廓的函数是findContours,它的输入图像是一幅二值图像, ...

  8. keras系列︱人脸表情分类与识别:opencv人脸检测+Keras情绪分类(四)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72885715 人脸识别热门,表情识别更加.但是表情识别很难,因为人脸的微表情很多,本节 ...

  9. OpenCV绘制检测结果

    OpenCV绘制检测结果 opencv  rtcp  timestamp  一.介绍 由于在验证阶段,使用FPGA时我们的算法检测速度很慢,没法直接在主流上进行绘图,否则的话,主流就要等待算法很久才能 ...

随机推荐

  1. BZOJ 3926 && ZJOI 2015 诸神眷顾的幻想乡 (广义后缀自动机)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec Memory Limit: 512 MB Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽 ...

  2. 高效的jQuery代码编写技巧总结

    最近写了很多的js,虽然效果都实现了,但是总感觉自己写的js在性能上还能有很大的提升.本文我计划总结一些网上找的和我本人的一些建议,来提升你的jQuery和javascript代码.好的代码会带来速度 ...

  3. Android-5 理解context

    context -- 用来访问全局信息 Application用途 Application生命周期 深入理解 Context http://blog.csdn.net/z1074971432/arti ...

  4. web后台获取不到session中的值(loading sessions from persistent storage),后改用JS传值

    线上的程序似乎从session中取不到domain数据,重启了一下tomcat查看log日志发现,居然有报错.错误信息如下 22-Sep-2016 00:52:16.562 SEVERE [local ...

  5. Java语言中有4种访问修饰符

    转载:http://wuhaidong.iteye.com/blog/851754 Java语言中有4种访问修饰符 在Java语言中有4中访问修饰符:package(默认).private.publi ...

  6. XJOI网上同步训练DAY2 T2

    [问题描述] 火车司机出秦川跳蚤国王下江南共价大爷游长沙.每个周末勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个

  7. LeetCode_Set Matrix Zeroes

    Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. 很挫的一个想 ...

  8. logstash 中的贪婪匹配

    logstash 中的贪婪匹配: 10.252.142.174 - - [06/Sep/2016:08:41:36 +0800] "GET /api/validate/code/send?m ...

  9. STL适配器的初步理解

    c++中的适配器有三种:容器适配器,迭代器适配器,函数适配器.下面一一介绍: 1.容器适配器:因为这些容器都是基于其他标准容器实现的所以叫做容器的适配器,具体的有stack,queue,priorit ...

  10. 最简单的XML转数组

    /** * 最简单的XML转数组 * @param string $xmlstring XML字符串 * @return array XML数组 */ function simplest_xml_to ...