圖像膚色初步檢測實現
阿新 • • 發佈:2019-04-16
oat sse ssi roc view views com var 處理
版權聲明:本文為博主原創文章,未經博主同意不得轉載。 https://blog.csdn.net/utimes/article/details/24836341
第三種:otsu閾值化
膚色檢測輸出結果中有很多瑕疵,待於進一步處理(如:濾波操作.....)。在此貼出幾種圖像膚色檢測相關代碼,供大家參考。
第一種: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;h<rgb->height;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;w<rgb->width;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;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=0;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=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<height;i++) { unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i; for(int j=0;j<width;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<=127
void 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;h<src->height;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;w<src->width;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);
關於Image Engineering & Computer Vision很多其它討論與交流,敬請關註本博客和新浪微博songzi_tea.
圖像膚色初步檢測實現