生活随笔
收集整理的這篇文章主要介紹了
                                
opencv 肤色
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
 
                                
                            
                            
                             先貼代碼
 
 
 
   [cpp] view plain
  copy      void?cvSkinSegment(IplImage*?img,?IplImage*?mask){?? ????CvSize?imageSize?=?cvSize(img->width,?img->height);?? ????IplImage?*imgY?=?cvCreateImage(imageSize,?IPL_DEPTH_8U,?1);?? ????IplImage?*imgCr?=?cvCreateImage(imageSize,?IPL_DEPTH_8U,?1);?? ????IplImage?*imgCb?=?cvCreateImage(imageSize,?IPL_DEPTH_8U,?1);?? ?????? ?????? ????IplImage?*imgYCrCb?=?cvCreateImage(imageSize,?img->depth,?img->nChannels);?? ????cvCvtColor(img,imgYCrCb,CV_BGR2YCrCb);?? ????cvSplit(imgYCrCb,?imgY,?imgCr,?imgCb,?0);?? ????int?y,?cr,?cb,?l,?x1,?y1,?value;?? ????unsigned?char?*pY,?*pCr,?*pCb,?*pMask;?? ?????? ????pY?=?(unsigned?char?*)imgY->imageData;?? ????pCr?=?(unsigned?char?*)imgCr->imageData;?? ????pCb?=?(unsigned?char?*)imgCb->imageData;?? ????pMask?=?(unsigned?char?*)mask->imageData;?? ????cvSetZero(mask);?? ????l?=?img->height?*?img->width;?? ????for?(int?i?=?0;?i?<?l;?i++){?? ????????y??=?*pY;?? ????????cr?=?*pCr;?? ????????cb?=?*pCb;?? ????????cb?-=?109;?? ????????cr?-=?152?? ????????????;?? ????????x1?=?(819*cr-614*cb)/32?+?51;?? ????????y1?=?(819*cr+614*cb)/32?+?77;?? ????????x1?=?x1*41/1024;?? ????????y1?=?y1*73/1024;?? ????????value?=?x1*x1+y1*y1;?? ????????if(y<100)????(*pMask)=(value<700)???255:0;?? ????????else????????(*pMask)=(value<850)??255:0;?? ????????pY++;?? ????????pCr++;?? ????????pCb++;?? ????????pMask++;?? ????}?? ????cvReleaseImage(&imgY);?? ????cvReleaseImage(&imgCr);?? ????cvReleaseImage(&imgCb);?? ????cvReleaseImage(&imgYCrCb);?? }?? 
 
 
 
 
 
 主要原理就是通過(guò)在Cb Cr空間上找到一個(gè)可以擬合常規(guī)膚色分布的橢圓形,然后把在橢圓形區(qū)域內(nèi)的像素點(diǎn)標(biāo)記為膚色
 
 
 
 圖1.1 橢圓模板示例
 
 
 
 
 以上插圖來(lái)源于《一種基于KL變換的橢圓模型膚色檢測(cè)方法?》,具體參數(shù)參考的那篇文獻(xiàn)時(shí)間久遠(yuǎn)找不到了
 
 ?
 
 以下是代碼運(yùn)行后的效果圖
 
 
 
 圖1.2 運(yùn)行效果1
 
 ?
 
 
 
 圖1.3 運(yùn)行效果2
 
 ?
 
 從上面兩圖可以看出,在光線(xiàn)條件比較理想的情況下,膚色檢測(cè)的效果還是不錯(cuò)的(1.2就比1.3效果好),但是對(duì)于一些似膚色區(qū)域(比如圖1.3后面的木質(zhì)門(mén)),還是會(huì)被誤檢,但這是膚色檢測(cè)無(wú)法解決的問(wèn)題。
 
 ?
 
 關(guān)于效果圖里面一些類(lèi)似噪點(diǎn)的部分,可以通過(guò)膨脹腐蝕模糊再二值化的方法取得比較圓潤(rùn)的膚色圖(就是可以做mask的)
 
 
 
   [c-sharp]?view plain
?copy      cvErode(pSkin,?pSkin,?NULL,?1);??????? cvDilate(pSkin,?pSkin,?NULL,?1);?? cvSmooth(pSkin,?pSkin,?CV_GAUSSIAN,?21,?0,?0);?? cvThreshold(pSkin,?pSkin,130,?255,?CV_THRESH_BINARY);?? 
 ? 
 
 當(dāng)然有時(shí)候效果也不是特別好,這個(gè)要靠自己調(diào)參數(shù)的。
 
 ?
 
 總體而言,與OpenCV2.0的adapativeskindetector.cpp相比的話(huà),效果要好(其實(shí)我改進(jìn)的代碼就是參照里面CvAdaptiveSkinDetector類(lèi)里的process函數(shù)的),當(dāng)然也有可能是因?yàn)槲业哪w色檢測(cè)是根據(jù)我所處環(huán)境的光照條件和攝像頭特性調(diào)節(jié)的緣故。
 
 ?
 
 最后,小小地對(duì)代碼作一個(gè)說(shuō)明。
 
 其實(shí)代碼很簡(jiǎn)單,就是把Y Cb Cr三個(gè)通道分開(kāi),然后用指針?lè)謩e對(duì)這三個(gè)通道的每一個(gè)像素進(jìn)行處理。
 
 需要作修改的就是if(y<100) (*pMask)=(value<700) ? 255:0;?else (*pMask)=(value<850)? 255:0; 這條做閾值判斷的命令
 
 由于光照和攝像頭性能的不同,這里的閾值需要根據(jù)自己的攝像頭調(diào)節(jié)出最合適的效果才可以
 
 ?
 
 另外的話(huà),對(duì)于質(zhì)量不是很好的WebCam 建議在輸入圖像上加一個(gè)小點(diǎn)的高斯模糊以去除噪點(diǎn)
 
 ?
 
 以上算法還曾經(jīng)作為我的大作業(yè)在Matlab和Xilinx FPGA上實(shí)現(xiàn),具體可以參考我的答辯PPT:Skin Segmentation on FPGA
                            總結(jié)
                            
                                以上是生活随笔為你收集整理的opencv 肤色的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                            
                                如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。