zoukankan      html  css  js  c++  java
  • Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图

     

    Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 

    分类: OpenCV图像处理
     
    原文链接  http://blog.csdn.net/yanzi1225627/article/details/8600169

        六种方法分别是:基于RGB分割,基于RG同道的分割,ycrcb+otsu(ostu可以参考http://blog.csdn.net/onezeros/article/details/6136770,

    http://wenku.baidu.com/view/05c47e03bed5b9f3f90f1ce4.html),YCrCb空间,YUV空间,HSV空间。下一步就是通过JNI将这些检测移植到android上,最终目标是实现Android智能手机利用掌纹开关机。

    环境是在qt下,.pro文件里增加如下代码:

    1. INCLUDEPATH += /usr/include/opencv  
    2.   
    3. LIBS += /usr/lib/libcv.so   
    4. /usr/lib/libcvaux.so   
    5. /usr/lib/libcxcore.so   
    6. /usr/lib/libhighgui.so   
    7. /usr/lib/libml.so  

    请看源码:
    1. #include <iostream>  
    2. #include "cv.h"  
    3. #include "highgui.h"  
    4.   
    5.   
    6. void SkinRGB(IplImage* rgb,IplImage* _dst);  
    7. void cvSkinRG(IplImage* rgb,IplImage* gray);  
    8. void cvThresholdOtsu(IplImage* src, IplImage* dst);  
    9. void cvSkinOtsu(IplImage* src, IplImage* dst);  
    10. void cvSkinYCbCr(IplImage* img, IplImage* mask);  
    11. void cvSkinYUV(IplImage* src,IplImage* dst);  
    12. void cvSkinHSV(IplImage* src,IplImage* dst);  
    13.   
    14.   
    15.   
    16.   
    17.   
    18.   
    19. using namespace std;  
    20.   
    21. // skin region location using rgb limitation  
    22.   
    23.   
    24.   
    25. int main()  
    26. {  
    27.     IplImage *srcImg = cvLoadImage("/home/yan/download/testPalm4.jpg", 1);  
    28.     IplImage *dstRGB = cvCreateImage(cvGetSize(srcImg), 8, 3);  
    29.     IplImage *dstRG = cvCreateImage(cvGetSize(srcImg), 8, 1);  
    30.     IplImage* dst_crotsu=cvCreateImage(cvGetSize(srcImg),8,1);  
    31.     IplImage* dst_ycbcr=cvCreateImage(cvGetSize(srcImg),8,1);  
    32.     IplImage* dst_yuv=cvCreateImage(cvGetSize(srcImg),8,3);  
    33.     IplImage* dst_hsv=cvCreateImage(cvGetSize(srcImg),8,3);  
    34.   
    35.     SkinRGB(srcImg, dstRGB);  
    36.     cvSaveImage("/home/yan/download/1_dstRGB.jpg", dstRGB);  
    37.   
    38.     cvSkinRG(srcImg, dstRG);  
    39.     cvSaveImage("/home/yan/download/2_dstRG.jpg", dstRG);  
    40.   
    41.     cvSkinOtsu(srcImg, dst_crotsu);  
    42.     cvSaveImage("/home/yan/download/3_dst_crotsu.jpg", dst_crotsu);  
    43.   
    44.     cvSkinYCbCr(srcImg, dst_ycbcr);  
    45.     cvSaveImage("/home/yan/download/4_dst_ycbcr.jpg", dst_ycbcr);  
    46.   
    47.     cvSkinYUV(srcImg, dst_yuv);  
    48.     cvSaveImage("/home/yan/download/5_dst_yuv.jpg", dst_yuv);  
    49.   
    50.     cvSkinHSV(srcImg, dst_hsv);  
    51.     cvSaveImage("/home/yan/download/6_dst_hsv.jpg", dst_hsv);  
    52.   
    53.   
    54.     cvNamedWindow("srcImg", 1);  
    55.     cvShowImage("srcImg", srcImg);  
    56.   
    57.     cvNamedWindow("dstRGB", 1);  
    58.     cvShowImage("dstRGB", dstRGB);  
    59.   
    60.     cvNamedWindow("dstRG", 1);  
    61.     cvShowImage("dstRG", dstRG);  
    62.   
    63.     cvNamedWindow("dstcrotsu", 1);  
    64.     cvShowImage("dstcrotsu", dst_crotsu);  
    65.   
    66.     cvNamedWindow("dst_ycbcr", 1);  
    67.     cvShowImage("dst_ycbcr", dst_ycbcr);  
    68.   
    69.     cvNamedWindow("dst_yuv", 1);  
    70.     cvShowImage("dst_yuv", dst_yuv);  
    71.   
    72.     cvNamedWindow("dst_hsv", 1);  
    73.     cvShowImage("dst_hsv", dst_hsv);  
    74.     cvWaitKey(0);  
    75.     cout << "Hello World!" << endl;  
    76.     return 0;  
    77. }  
    78. void SkinRGB(IplImage* rgb,IplImage* _dst)  
    79. {  
    80.     cout<<"111"<<endl;  
    81.     assert(rgb->nChannels==3&& _dst->nChannels==3);  
    82.   
    83.     static const int R=2;  
    84.     static const int G=1;  
    85.     static const int B=0;  
    86.   
    87.     IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);  
    88.     cvZero(dst);  
    89.   
    90.     for (int h=0;h<rgb->height;h++) {  
    91.         unsigned char* prgb=(unsigned char*)rgb->imageData+h*rgb->widthStep;  
    92.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
    93.         for (int w=0;w<rgb->width;w++) {  
    94.             if ((prgb[R]>95 && prgb[G]>40 && prgb[B]>20 &&  
    95.                  prgb[R]-prgb[B]>15 && prgb[R]-prgb[G]>15/*&& 
    96.                      !(prgb[R]>170&&prgb[G]>170&&prgb[B]>170)*/)||//uniform illumination  
    97.                     (prgb[R]>200 && prgb[G]>210 && prgb[B]>170 &&  
    98.                      abs(prgb[R]-prgb[B])<=15 && prgb[R]>prgb[B]&& prgb[G]>prgb[B])//lateral illumination  
    99.                     ) {  
    100.                 memcpy(pdst,prgb,3);  
    101.             }  
    102.             prgb+=3;  
    103.             pdst+=3;  
    104.         }  
    105.     }  
    106.     cvCopyImage(dst,_dst);  
    107.     cvReleaseImage(&dst);  
    108. }  
    109.   
    110. void cvSkinRG(IplImage* rgb,IplImage* gray)  
    111. {  
    112.     assert(rgb->nChannels==3&&gray->nChannels==1);  
    113.   
    114.     const int R=2;  
    115.     const int G=1;  
    116.     const int B=0;  
    117.   
    118.     double Aup=-1.8423;  
    119.     double Bup=1.5294;  
    120.     double Cup=0.0422;  
    121.     double Adown=-0.7279;  
    122.     double Bdown=0.6066;  
    123.     double Cdown=0.1766;  
    124.     for (int h=0; h<rgb->height; h++)  
    125.     {  
    126.         unsigned char* pGray=(unsigned char*)gray->imageData+h*gray->widthStep;  
    127.         unsigned char* pRGB=(unsigned char* )rgb->imageData+h*rgb->widthStep;  
    128.         for (int w=0; w<rgb->width; w++)  
    129.         {  
    130.             int s=pRGB[R]+pRGB[G]+pRGB[B];  
    131.             double r=(double)pRGB[R]/s;  
    132.             double g=(double)pRGB[G]/s;  
    133.             double Gup=Aup*r*r+Bup*r+Cup;  
    134.             double Gdown=Adown*r*r+Bdown*r+Cdown;  
    135.             double Wr=(r-0.33)*(r-0.33)+(g-0.33)*(g-0.33);  
    136.             if (g<Gup && g>Gdown && Wr>0.004)  
    137.             {  
    138.                 *pGray=255;  
    139.             }  
    140.             else  
    141.             {  
    142.                 *pGray=0;  
    143.             }  
    144.             pGray++;  
    145.             pRGB+=3;  
    146.         }  
    147.     }  
    148.   
    149. }  
    150. void cvThresholdOtsu(IplImage* src, IplImage* dst)  
    151. {  
    152.     int height=src->height;  
    153.     int width=src->width;  
    154.   
    155.     //histogram  
    156.     float histogram[256]= {0};  
    157.     for(int i=0; i<height; i++)  
    158.     {  
    159.         unsigned char* p=(unsigned char*)src->imageData+src->widthStep*i;  
    160.         for(int j=0; j<width; j++)  
    161.         {  
    162.             histogram[*p++]++;  
    163.         }  
    164.     }  
    165.     //normalize histogram  
    166.     int size=height*width;  
    167.     for(int i=0; i<256; i++)  
    168.     {  
    169.         histogram[i]=histogram[i]/size;  
    170.     }  
    171.   
    172.     //average pixel value  
    173.     float avgValue=0;  
    174.     for(int i=0; i<256; i++)  
    175.     {  
    176.         avgValue+=i*histogram[i];  
    177.     }  
    178.   
    179.     int threshold;  
    180.     float maxVariance=0;  
    181.     float w=0,u=0;  
    182.     for(int i=0; i<256; i++)  
    183.     {  
    184.         w+=histogram[i];  
    185.         u+=i*histogram[i];  
    186.   
    187.         float t=avgValue*w-u;  
    188.         float variance=t*t/(w*(1-w));  
    189.         if(variance>maxVariance)  
    190.         {  
    191.             maxVariance=variance;  
    192.             threshold=i;  
    193.         }  
    194.     }  
    195.     cvThreshold(src,dst,threshold,255,CV_THRESH_BINARY);  
    196. }  
    197.   
    198. void cvSkinOtsu(IplImage* src, IplImage* dst)  
    199. {  
    200.     assert(dst->nChannels==1&& src->nChannels==3);  
    201.   
    202.     IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
    203.     IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
    204.     cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
    205.     cvSplit(ycrcb,0,cr,0,0);  
    206.   
    207.     cvThresholdOtsu(cr,cr);  
    208.     cvCopyImage(cr,dst);  
    209.     cvReleaseImage(&cr);  
    210.     cvReleaseImage(&ycrcb);  
    211. }  
    212. void cvSkinYCbCr(IplImage* img, IplImage* mask)  
    213. {  
    214.     CvSize imageSize = cvSize(img->width, img->height);  
    215.     IplImage *imgY = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);  
    216.     IplImage *imgCr = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);  
    217.     IplImage *imgCb = cvCreateImage(imageSize, IPL_DEPTH_8U, 1);  
    218.   
    219.   
    220.     IplImage *imgYCrCb = cvCreateImage(imageSize, img->depth, img->nChannels);  
    221.     cvCvtColor(img,imgYCrCb,CV_BGR2YCrCb);  
    222.     cvSplit(imgYCrCb, imgY, imgCr, imgCb, 0);  
    223.     int y, cr, cb, l, x1, y1, value;  
    224.     unsigned char *pY, *pCr, *pCb, *pMask;  
    225.   
    226.     pY = (unsigned char *)imgY->imageData;  
    227.     pCr = (unsigned char *)imgCr->imageData;  
    228.     pCb = (unsigned char *)imgCb->imageData;  
    229.     pMask = (unsigned char *)mask->imageData;  
    230.     cvSetZero(mask);  
    231.     l = img->height * img->width;  
    232.     for (int i = 0; i < l; i++){  
    233.         y  = *pY;  
    234.         cr = *pCr;  
    235.         cb = *pCb;  
    236.         cb -= 109;  
    237.         cr -= 152  
    238.                 ;  
    239.         x1 = (819*cr-614*cb)/32 + 51;  
    240.         y1 = (819*cr+614*cb)/32 + 77;  
    241.         x1 = x1*41/1024;  
    242.         y1 = y1*73/1024;  
    243.         value = x1*x1+y1*y1;  
    244.         if(y<100)    (*pMask)=(value<700) ? 255:0;  
    245.         else        (*pMask)=(value<850)? 255:0;  
    246.         pY++;  
    247.         pCr++;  
    248.         pCb++;  
    249.         pMask++;  
    250.     }  
    251.     cvReleaseImage(&imgY);  
    252.     cvReleaseImage(&imgCr);  
    253.     cvReleaseImage(&imgCb);  
    254.     cvReleaseImage(&imgYCrCb);  
    255. }  
    256.   
    257. void cvSkinYUV(IplImage* src,IplImage* dst)  
    258. {  
    259.     IplImage* ycrcb=cvCreateImage(cvGetSize(src),8,3);  
    260.     //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
    261.     //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);  
    262.     cvCvtColor(src,ycrcb,CV_BGR2YCrCb);  
    263.     //cvSplit(ycrcb,0,cr,cb,0);  
    264.   
    265.     static const int Cb=2;  
    266.     static const int Cr=1;  
    267.     static const int Y=0;  
    268.   
    269.     //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);  
    270.     cvZero(dst);  
    271.   
    272.     for (int h=0; h<src->height; h++)  
    273.     {  
    274.         unsigned char* pycrcb=(unsigned char*)ycrcb->imageData+h*ycrcb->widthStep;  
    275.         unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;  
    276.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
    277.         for (int w=0; w<src->width; w++)  
    278.         {  
    279.             if (pycrcb[Cr]>=133&&pycrcb[Cr]<=173&&pycrcb[Cb]>=77&&pycrcb[Cb]<=127)  
    280.             {  
    281.                 memcpy(pdst,psrc,3);  
    282.             }  
    283.             pycrcb+=3;  
    284.             psrc+=3;  
    285.             pdst+=3;  
    286.         }  
    287.     }  
    288.     //cvCopyImage(dst,_dst);  
    289.     //cvReleaseImage(&dst);  
    290. }  
    291.   
    292. void cvSkinHSV(IplImage* src,IplImage* dst)  
    293. {  
    294.     IplImage* hsv=cvCreateImage(cvGetSize(src),8,3);  
    295.     //IplImage* cr=cvCreateImage(cvGetSize(src),8,1);  
    296.     //IplImage* cb=cvCreateImage(cvGetSize(src),8,1);  
    297.     cvCvtColor(src,hsv,CV_BGR2HSV);  
    298.     //cvSplit(ycrcb,0,cr,cb,0);  
    299.   
    300.     static const int V=2;  
    301.     static const int S=1;  
    302.     static const int H=0;  
    303.   
    304.     //IplImage* dst=cvCreateImage(cvGetSize(_dst),8,3);  
    305.     cvZero(dst);  
    306.   
    307.     for (int h=0; h<src->height; h++)  
    308.     {  
    309.         unsigned char* phsv=(unsigned char*)hsv->imageData+h*hsv->widthStep;  
    310.         unsigned char* psrc=(unsigned char*)src->imageData+h*src->widthStep;  
    311.         unsigned char* pdst=(unsigned char*)dst->imageData+h*dst->widthStep;  
    312.         for (int w=0; w<src->width; w++)  
    313.         {  
    314.             if (phsv[H]>=7&&phsv[H]<=29)  
    315.             {  
    316.                 memcpy(pdst,psrc,3);  
    317.             }  
    318.             phsv+=3;  
    319.             psrc+=3;  
    320.             pdst+=3;  
    321.         }  
    322.     }  
    323.     //cvCopyImage(dst,_dst);  
    324.     //cvReleaseImage(&dst);  
    325. }  
    下面是效果图:

    测试图片:

    下图的贴图依次对应上面的六种方法:

    从上面的结果对比图中可以清晰看的,ycrcb+ostu的效果无疑是最好的。其次是rgb和yuv方法。这个图片效果之所以这么好是因为测试图片拍摄的时候背景为白色。然后,遗憾的是,当背景色不纯的时候,比如有红也有黑,效果就很不理想了。实验发现,当背景为纯色,且是白色或黑色时,效果最好。

    参考:

    http://blog.sina.com.cn/s/blog_9ce5a1b501017otq.html

    http://blog.csdn.net/scyscyao/article/details/5468577

    http://wenku.baidu.com/view/05c47e03bed5b9f3f90f1ce4.html

    http://blog.csdn.net/onezeros/article/details/6136770

        --------------------------本掌纹是作者自己的,转载请注明作者yanzi1225627

  • 相关阅读:
    Navicat连接mysql出现10061/10060错误的解决
    对话守则
    一次Django admin bug解决的思维过程
    Think different
    SVN版本库的迁移
    Windows Phone 8 锁屏背景与通知
    Windows Phone 7 应用升级 Windows phone 8 方案预览 选择合适的 Key Feature
    从 windows phone7 到 windows phone 8 更新 如何设配两个版本
    windows phone 8 语音 Speech for Windows Phone 8
    windows phone 8 中的应用间通信
  • 原文地址:https://www.cnblogs.com/qingchen1984/p/4972566.html
Copyright © 2011-2022 走看看