yuv肤色检测 matlab,图像肤色初步检测实现

肤色检测输出结果中有许多瑕疵,待于进一步处理(如:滤波操作.....)。在此贴出几种图像肤色检测相关代码,供大家参考。

第一种:RGB color space// skin region location using rgb limitation

void ImageSkin::ImageSkinRGB(IplImage* rgb,IplImage* _dst)

{

assert(rgb->nChannels==3&& _dst->nChannels==3);

static const int R=2;

static const int G=1;

static const int B=0;

IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);

cvZero(dst);

for (int h=0;hheight;h++) {

unsigned char* prgb=(unsigned char*)rgb->imageData+h*rgb->widthStep;

unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;

for (int w=0;wwidth;w++) {

if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&

prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15)||//uniform illumination

(prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&

abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])

) {

memcpy(pdst,prgb,3);

}

prgb+=3;

pdst+=3;

}

}

cvCopyImage(dst,_dst);

cvReleaseImage(&dst);

}

第二种:RG color space// skin detection in rg space

void ImageSkin::ImageSkinRG(IplImage* rgb,IplImage* gray)

{

assert(rgb->nChannels==3&&gray->nChannels==1);

const int R=2;

const int G=1;

const int B=0;

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=0;hheight;h++) {

unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;

unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;

for (int w=0;wwidth;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 (gGdown && Wr>0.004)

{

*pGray=255;

}

else

{

*pGray=0;

}

pGray++;

pRGB+=3;

}

}

}

第三种:otsu阈值化// reference: Rafael C. Gonzalez. Digital Image Processing Using MATLAB

void ImageSkin::ImageThresholdOtsu(IplImage* src, IplImage* dst)

{

int height=src->height;

int width=src->width;

//histogram

float histogram[256]={0};

for(int i=0;i

unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;

for(int j=0;j

histogram[*p++]++;

}

}

//normalize histogram

int size=height*width;

for(int i=0;i<256;i++) {

histogram[i]=histogram[i]/size;

}

//average pixel value

float avgValue=0;

for(int i=0;i<256;i++) {

avgValue+=i*histogram[i];

}

int threshold;

float maxVariance=0;

float w=0,u=0;

for(int i=0;i<256;i++) {

w+=histogram[i];

u+=i*histogram[i];

float t=avgValue*w-u;

float variance=t*t/(w*(1-w));

if(variance>maxVariance) {

maxVariance=variance;

threshold=i;

}

}

cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);

}

第四种:Ycrcb之cr分量+otsu阈值化void ImageSkin::ImageSkinOtsu(IplImage* src, IplImage* dst)

{

assert(dst->nChannels==1&& src->nChannels==3);

IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);

IplImage* cr=cvCreateImage(cvGetSize(src),8,1);

cvCvtColor(src,ycrcb,CV_BGR2YCrCb);

cvSplit(ycrcb,0,cr,0,0);

ImageThresholdOtsu(cr,cr);

cvCopyImage(cr,dst);

cvReleaseImage(&cr);

cvReleaseImage(&ycrcb);

}

第五种:YCrCb中133<=Cr<=173 77<=Cb<=127void ImageSkin::ImageSkinYUV(IplImage* src,IplImage* dst)

{

IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);

//IplImage* cr=cvCreateImage(cvGetSize(src),8,1);

//IplImage* cb=cvCreateImage(cvGetSize(src),8,1);

cvCvtColor(src,ycrcb,CV_BGR2YCrCb);

//cvSplit(ycrcb,0,cr,cb,0);

static const int Cb=2;

static const int Cr=1;

static const int Y=0;

//IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);

cvZero(dst);

for (int h=0;hheight;h++) {

unsigned char* pycrcb=(unsigned char*)ycrcb->imageData+h*ycrcb->widthStep;

unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;

unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;

for (int w=0;wwidth;w++) {

if (pycrcb[Cr]>=133&&pycrcb[Cr]<=173&&pycrcb[Cb]>=77&&pycrcb[Cb]<=127)

{

memcpy(pdst,psrc,3);

}

pycrcb+=3;

psrc+=3;

pdst+=3;

}

}

//cvCopyImage(dst,_dst);

//cvReleaseImage(&dst);

}

主程序测试IplImage* img= cvLoadImage("test.jpg");

IplImage* dstRGB=cvCreateImage(cvGetSize(img),8,3);

IplImage* dstRG=cvCreateImage(cvGetSize(img),8,1);

IplImage* dst_crotsu=cvCreateImage(cvGetSize(img),8,1);

IplImage* dst_YUV=cvCreateImage(cvGetSize(img),8,3);

cvNamedWindow("Original WIN", CV_WINDOW_AUTOSIZE);

cvShowImage("Original WIN", img);

cvWaitKey(0);

ImageSkin ImgS;

ImgS.ImageSkinRGB(img,dstRGB);

cvNamedWindow("ImageSkin WIN", CV_WINDOW_AUTOSIZE);

cvShowImage("ImageSkin WIN", dstRGB);

cvWaitKey(0);

ImgS.ImageSkinRG(img,dstRG);

cvNamedWindow("ImageSkinRG WIN", CV_WINDOW_AUTOSIZE);

cvShowImage("ImageSkinRG WIN", dstRG);

cvWaitKey(0);

ImgS.ImageSkinOtsu(img,dst_crotsu);

cvNamedWindow("ImageSkinOtsu WIN", CV_WINDOW_AUTOSIZE);

cvShowImage("ImageSkinOtsu WIN", dst_crotsu);

cvWaitKey(0);

ImgS.ImageSkinYUV(img,dst_YUV);

cvNamedWindow("ImageSkinYUV WIN", CV_WINDOW_AUTOSIZE);

cvShowImage("ImageSkinYUV WIN", dst_YUV);

《探讨OpenCV》专栏QQ群:195358461

关于Image Engineering & Computer Vision更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.

原文:http://blog.csdn.net/songzitea/article/details/24836341

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值