一个简单有趣的皮肤检测代码

来源:互联网 发布:2016年云计算发展趋势 编辑:程序博客网 时间:2024/06/03 02:37

Cite From: http://www.cnblogs.com/tornadomeet/archive/2012/12/05/2802428.html

前言

  最近课题研究上想采用皮肤信息,但是个人总是对皮肤信息应用在目标检测和目标识别上有排斥,认为皮肤信息完全不足以胜任这个工作。其实计算机视觉的最终实现是一个长期的过程,是AI领域一个经典的问题,所以在AI完全突破之前,任何对CV有用的信息都值得去深入研究,除非有一种算法能够在所有情况下都工作。好了,废话不扯了,进入正题,有偏见但是还是得使用它。皮肤模型中有单高斯,混合高斯,贝叶斯模型和椭圆模型等。经过前人学者大量的皮肤统计信息可以知道,如果将皮肤信息映射到YCrCb空间,则在CrCb二维空间中这些皮肤像素点近似成一个椭圆分布。因此如果我们得到了一个CrCb的椭圆,下次来一个坐标(Cr, Cb)我们只需判断它是否在椭圆内(包括边界),如果是,则可以判断其为皮肤,否则就是非皮肤像素点。

  开发环境:OpenCV2.4.3+QtCreator2.5.1

  实验基础

  本实验是参考小短文A super-simple skin detector in OpenCV,该文章里面首先直接给出了一个比较合理的椭圆,即该椭圆能够代表大部分人的皮肤信息CrCb的分布。椭圆的分布如下:

  

  说它比较有趣是因为我们是用一副图像来存储上面的椭圆的,而不是直接采用椭圆数学方程。该图像是二值图像,即椭圆区域内部为白色,其它地方为黑色。所以当其需要判断其它像素点时,只需将该像素点转换成Cr,Cb两个坐标,然后在上面的椭圆中找到该坐标的值,如果非0,则为皮肤,反之亦然。

  在实际代码中,该椭圆是采用绘画函数绘制到图片上的,一句代码而已:

ellipse(skinCrCbHist, Point(113, 155.6), Size(23.4, 15.2), 43.0, 0.0, 360.0, Scalar(255, 255, 255), -1);

  void ellipse(Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar&color, int thickness=1, int lineType=8, int shift=0)

  该函数是用来在指定图片上绘制椭圆弧线的。

  参数image为需要绘制椭圆的图像;

  参数center是该椭圆的中心点坐标;

  参数axes是该椭圆的长半轴和短半轴;

  参数angle是该椭圆和水平方向上的旋转夹角;

  参数startAngle表示绘制椭圆弧线相对该椭圆自己的水平轴的起始角度;

  参数endAngel表示绘制椭圆弧线相对该椭圆自己的水平轴的终止角度;

  后面的参数比较普通就不介绍了。

  绘制椭圆曲线的示意图如下所示:

  

  实验结果

  检测前的图像:

  

  利用该算法进行皮肤检测后的二值图:

  

  实验代码及注释

  main.cpp:

#include <cv.h>#include <cxcore.h>#include <highgui.h>

#include <iostream>#include <iomanip>#include <algorithm>using namespace std;using namespace cv;

int main(){  char * ImageName = "f.jpg";  //椭圆皮肤模型 Mat skinCrCbHist = Mat::zeros(Size(256,256),CV_8UC1); ellipse(skinCrCbHist,Point(113,155.6),Size(23.4,15.2),43.0,0.0,360.0,  Scalar(255,255,255),-1); IplImage * inputimage = cvLoadImage(ImageName,CV_LOAD_IMAGE_COLOR); if(!inputimage)  return -1; CvSize imgSize = cvSize(inputimage->width,inputimage->height); Mat output = Mat::zeros(cvSize(inputimage->width,inputimage->height),CV_8UC1); IplImage *imgY = cvCreateImage(imgSize,IPL_DEPTH_8U,1); IplImage *imgCr = cvCreateImage(imgSize,IPL_DEPTH_8U,1); IplImage *imgCb = cvCreateImage(imgSize,IPL_DEPTH_8U,1);

 IplImage * imgYCrCb = cvCreateImage(imgSize,inputimage->depth,inputimage->nChannels); cvCvtColor(inputimage,imgYCrCb,CV_BGR2YCrCb); cvSplit(imgYCrCb,imgY,imgCr,imgCb,0);//获得图像的每个分量 CvScalar ycrcb; for(int i =0;i<imgYCrCb->width;i++)  for(int j=0;j<imgYCrCb->height;j++)  {   ycrcb = cvGet2D(imgYCrCb,j,i);   if(skinCrCbHist.at<uchar>(ycrcb.val[1],ycrcb.val[2])>0)    output.at<uchar>(j,i) = 255;  } cvShowImage("orig",inputimage); imshow("tem",output); while(1) {  if(cvWaitKey(100) == 27)   break; } //fingerTip(ImageName); cvReleaseImage(&inputimage); return 0;}

  实验总结: 皮肤的椭圆模型确实可以用来做皮肤检测,一旦确定好了该椭圆就可以用来做皮肤检测了。

  参考文献:

A super-simple skin detector in OpenCV

皮肤检测与克服光线影响的连通域寻找

 http://docs.opencv.org/modules/core/doc/drawing_functions.html?highlight=ellipse#cv.Ellipse

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 游拍主播申请手机号被注册怎么办 淘宝客不给力怎么办 淘宝买家确认收货超时怎么办 淘宝没收到货退款卖家不处理怎么办 微博红包都是字怎么办 500个访客没转化怎么办 店铺动态评分是0怎么办 京东店铺评分低怎么办 被淘宝主播屏蔽怎么办 在淘宝客推广后退款怎么办 生产出现异常时你应该怎么办 违规后的店铺没访客怎么办 淘宝少发货店家不承认怎么办 淘宝买东西店家不发货怎么办 淘宝店家拒绝同意退款怎么办 被淘宝店家骂了怎么办 淘宝买家骂店家骚扰店家怎么办? 不想开淘宝店了怎么办 我是客服经常有客户骂人怎么办 淘宝直播前期没人看怎么办 淘宝被投诉商标侵权怎么办 淘宝后商家页面打不开了怎么办 淘宝遇到职业打假人怎么办 发票被复写上字怎么办 淘宝直播广告图片的商品怎么办 美团商家排名低怎么办 想成为淘宝主播怎么办 用移动流量很卡怎么办 淘宝店铺被恶意刷流量怎么办 一个想要公司权利的人怎么办 淘宝商家短信推广告怎么办 在群里乱发信息怎么办 支付宝扫不了码怎么办 淘宝商家收款不发货怎么办 淘宝申请退款商家拒绝怎么办 一件代发找不到供货商怎么办 淘宝京东兼职上当怎么办 退货时快递丢件怎么办 淘宝店铺代销1688有订单怎么办 供应商已解除合作无法代销怎么办 被代运营骗了怎么办