• 图像处理------基于像素的皮肤检测技术 分类: 视频图像处理 2015-07-24 09:56 28人阅读 评论(0) 收藏


    基于像素的皮肤检测技术

    介绍一种基于颜色空间的皮肤检测技术,可以检测亚洲人种与白人的皮肤,皮肤检测

    人脸识别的基础,也是很多人像识别技术的基础操作,在实际应用中还是非常有用的。

     

    基于像素的皮肤检测主要是寻找正确的颜色空间几何,图像处理中,常见的颜色空间

    有如下几种

    1.      RGB色彩空间 – R代表单色红,G代表单色绿,B代表单色蓝

    2.      HSV色彩空间 – H 代表色彩, S代表饱和度,V代表强度值

    3.      YCbCr色彩空间 – 是数字电视的色彩空间

     

    RGB转换为HSV的Java代码如下:

    1. public static float[] rgbToHSV(int tr, int tg, int tb) {  
    2.     float min, max, delta;  
    3.     float hue, satur, value;  
    4.     min = Math.min(tr, Math.min(tg, tb));  
    5.     max = Math.max(tr, Math.max(tg, tb));  
    6.     value = max;  
    7.     delta = max - min;  
    8.     if(max != 0) {  
    9.         satur = delta/max;  
    10.     } else {  
    11.         satur = 0;  
    12.         hue = -1;  
    13.     }  
    14.       
    15.     if(tr == max) {  
    16.         hue = (tg - tb)/delta;  
    17.     }  
    18.     else if(tg == max) {  
    19.         hue = 2 + (tb-tr)/delta;  
    20.     } else {  
    21.         hue = 4 + (tr-tg)/delta;  
    22.     }  
    23.     hue = hue * 60.0f;  
    24.     if(hue < 0) {  
    25.         hue = hue + 360;  
    26.     }  
    27.     return new float[]{hue, satur, value};  
    28. }  

    RGB转换为YCbCr的Java代码如下:

    1. public static int[] rgbToYcrCb(int tr, int tg, int tb) {  
    2.     double sum = tr + tg + tb;  
    3.     double r = ((double)tr)/sum;  
    4.     double g = ((double)tg)/sum;  
    5.     double b = ((double)tb)/sum;  
    6.     double y = 65.481 * r + 128.553 * g + 24.966 * b + 16.0d;  
    7.     double Cr = -37.7745 * r - 74.1592 * g + 111.9337 * b + 128.0d;  
    8.     double Cb = 111.9581 * r -93.7509 * g -18.2072 * b + 128.0d;  
    9.     return new int[]{(int)y, (int)Cr, (int)Cb};  
    10. }  
    一个简单的基于RGB颜色空间的皮肤算法如下:

    (R, G, B) is classified as skin if

    R > 95 and G > 40 and B > 20and max{R, G, B} – min{R, G, B} > 15 and |R-G| > 15

    and R > G and R > B

    实现代码如下:

    1. public boolean isSkin(int tr, int tg, int tb) {  
    2.     int max = Math.max(tr, Math.max(tg, tb));  
    3.     int min = Math.min(tr, Math.min(tg, tb));  
    4.     int rg = Math.abs(tr - tg);  
    5.     if(tr > 95 && tg > 40 && tb > 20 && rg > 15 &&   
    6.             (max - min) > 15 && tr > tg && tr > tb) {  
    7.         return true;  
    8.     } else {  
    9.         return false;  
    10.     }  
    11. }  

    一个简单的基于HSV颜色空间的皮肤算法如下:

    (H, S, V) will be classified as skin if

    H > 0 and H < 50 and S > 0.23 andS < 0.68

    实现代码如下:

    1. public boolean isSkin(int tr, int tg, int tb) {  
    2.     float[] HSV = ColorUtil.rgbToHSV(tr, tg, tb);  
    3.     if((HSV[0] > 0.0f && HSV[0] < 50.0f ) && (HSV[1] > 0.23f && HSV[1] < 0.68f)){  
    4.         return true;  
    5.     } else {  
    6.         return false;  
    7.     }  
    8. }  

    一个简单的基于YCbCr颜色空间的皮肤算法如下:

    (Y, Cb, Cr) will be classified as skin if:

    > 80 and 85<Cb < 135 and 135 <Cr < 180, and (Y,Cb,Cr)= [0,255] 

    对于的Java代码如下:

    1. public boolean isSkin(int tr, int tg, int tb) {  
    2.     int y = (int)(tr * 0.299 + tg * 0.587 + tb * 0.114);  
    3.     int Cr = tr - y;  
    4.     int Cb = tb - y;  
    5.     if(y> 80 && y < 255 && Cr > 133 && Cr < 173 && 77 < Cb && Cb < 127) {  
    6.         return true;  
    7.     }  
    8.     return false;  
    9. }  
    基于上述三个算法实现的皮肤检测的效果如下:


    皮肤检测滤镜的源代码如下:

    1. package com.process.blur.study;  
    2.   
    3. import java.awt.Color;  
    4. import java.awt.image.BufferedImage;  
    5.   
    6. import com.gloomyfish.skin.dection.DefaultSkinDetection;  
    7. import com.gloomyfish.skin.dection.FastSkinDetection;  
    8. import com.gloomyfish.skin.dection.GaussianSkinDetection;  
    9. import com.gloomyfish.skin.dection.HSVSkinDetection;  
    10. import com.gloomyfish.skin.dection.ISkinDetection;  
    11.   
    12. public class SkinFilter extends AbstractBufferedImageOp {  
    13.     private ISkinDetection skinDetector;  
    14.       
    15.     public SkinFilter(int type) {  
    16.         if(type == 2) {  
    17.             skinDetector = new FastSkinDetection();  
    18.         } else if(type == 4) {  
    19.             skinDetector = new HSVSkinDetection();  
    20.         } else if(type == 8) {  
    21.             skinDetector = new GaussianSkinDetection();  
    22.         } else {  
    23.             skinDetector = new DefaultSkinDetection();  
    24.         }  
    25.     }  
    26.   
    27.     @Override  
    28.     public BufferedImage filter(BufferedImage src, BufferedImage dst) {  
    29.         int width = src.getWidth();  
    30.         int height = src.getHeight();  
    31.   
    32.         if ( dst == null )  
    33.             dst = createCompatibleDestImage( src, null );  
    34.   
    35.         int[] inPixels = new int[width*height];  
    36.         int[] outPixels = new int[width*height];  
    37.         getRGB( src, 00, width, height, inPixels );  
    38.         if(skinDetector instanceof GaussianSkinDetection) {  
    39.             ((GaussianSkinDetection)skinDetector).setDispSample(getDispersion(src));  
    40.         }  
    41.         int index = 0;  
    42.         for(int row=0; row<height; row++) {  
    43.             int ta = 0, tr = 0, tg = 0, tb = 0;  
    44.             for(int col=0; col<width; col++) {  
    45.                 index = row * width + col;  
    46.                 ta = (inPixels[index] >> 24) & 0xff;  
    47.                 tr = (inPixels[index] >> 16) & 0xff;  
    48.                 tg = (inPixels[index] >> 8) & 0xff;  
    49.                 tb = inPixels[index] & 0xff;  
    50.                 if(skinDetector.isSkin(tr, tg, tb)) {  
    51.                     outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
    52.                 } else {  
    53.                     tr = tg = tb = 0;  
    54.                     outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
    55.                 }                 
    56.             }  
    57.         }  
    58.         setRGB( dst, 00, width, height, outPixels );  
    59.         return dst;  
    60.     }  
    61.       
    62.     public Color getDispersion(BufferedImage image) {  
    63.         // calculate means of pixel    
    64.         int index = 0;  
    65.         int height = image.getHeight();  
    66.         int width = image.getWidth();  
    67.         int[] inPixels = new int[width*height];  
    68.         getRGB(image, 00, width, height, inPixels );  
    69.         double redSum = 0, greenSum = 0, blueSum = 0;  
    70.         Color meanColor = getMean(image);  
    71.         double redmeans = meanColor.getRed();  
    72.         double greenmeans = meanColor.getGreen();  
    73.         double bluemeans = meanColor.getBlue();  
    74.         double total = height * width;    
    75.         for(int row=0; row<height; row++) {    
    76.             int ta = 0, tr = 0, tg = 0, tb = 0;    
    77.             for(int col=0; col<width; col++) {    
    78.                 index = row * width + col;    
    79.                 ta = (inPixels[index] >> 24) & 0xff;    
    80.                 tr = (inPixels[index] >> 16) & 0xff;    
    81.                 tg = (inPixels[index] >> 8) & 0xff;    
    82.                 tb = inPixels[index] & 0xff;   
    83.                 double rd = (tr - redmeans);  
    84.                 double gd = (tg - greenmeans);  
    85.                 double bd = (tb - bluemeans);  
    86.                 redSum += rd * rd;    
    87.                 greenSum += gd * gd;    
    88.                 blueSum += bd * bd;    
    89.             }    
    90.         }  
    91.         int reddiff = (int)Math.sqrt((redSum / total));  
    92.         int greendiff = (int)Math.sqrt((greenSum / total));  
    93.         int bluediff = (int)Math.sqrt(blueSum / total);  
    94.         System.out.println(" red dispersion value = " + reddiff);  
    95.         System.out.println(" green dispersion value = " + greendiff);  
    96.         System.out.println(" blue dispersion value = " + bluediff);  
    97.         return new Color(reddiff, greendiff, bluediff);  
    98.     }  
    99.       
    100.     public Color getMean(BufferedImage image) {  
    101.         // calculate means of pixel    
    102.         int index = 0;  
    103.         int height = image.getHeight();  
    104.         int width = image.getWidth();  
    105.         int[] inPixels = new int[width*height];  
    106.         getRGB(image, 00, width, height, inPixels );  
    107.         double redSum = 0, greenSum = 0, blueSum = 0;    
    108.         double total = height * width;    
    109.         for(int row=0; row<height; row++) {    
    110.             int ta = 0, tr = 0, tg = 0, tb = 0;    
    111.             for(int col=0; col<width; col++) {    
    112.                 index = row * width + col;    
    113.                 ta = (inPixels[index] >> 24) & 0xff;    
    114.                 tr = (inPixels[index] >> 16) & 0xff;    
    115.                 tg = (inPixels[index] >> 8) & 0xff;    
    116.                 tb = inPixels[index] & 0xff;    
    117.                 redSum += tr;    
    118.                 greenSum += tg;    
    119.                 blueSum +=tb;    
    120.             }    
    121.         }  
    122.         int redmeans = (int)(redSum / total);  
    123.         int greenmeans = (int)(greenSum / total);  
    124.         int bluemeans = (int)(blueSum / total);  
    125.         System.out.println(" red average value = " + redmeans);  
    126.         System.out.println(" green average value = " + greenmeans);  
    127.         System.out.println(" blue average value = " + bluemeans);  
    128.         return new Color(redmeans, greenmeans, bluemeans);  
    129.     }  
    130. }  

    讨论:

    皮肤检测中的后续处理非常重要,可以除去噪声,平滑图像,是皮肤检测的结果

    更加的准确,输出的更容易接受。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    2017-5-25 母版页
    2017-5-25 分页加条件查询合体
    2017-5-23 WebForm 中的分页功能和条件查询功能
    2017-5-17 WebForm 基础
    2017-5-14 心情
    2017-5-10 小型人员管理系统
    2017-5-9 打开唯一窗体的实例操作
    2017-5-8 TreeView 实现三级联动 (递归方法)
    2017-5-7 三级联动数据库 数据保存
    2017-5-7 三级联动
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706365.html
Copyright © 2020-2023  润新知