五种基于RGB色彩空间统计的皮肤检测算法

简介: <p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">最近一直在研究多脸谱识别以及如何分辨多个皮肤区域是否是人脸的问题<br></p><p style="color: rgb(51, 51, 51); font-family: Arial; font-size: 1

最近一直在研究多脸谱识别以及如何分辨多个皮肤区域是否是人脸的问题

网上找了很多资料,看了很多篇文章,将其中基于RGB色彩空间识别皮肤

的统计算法做了一下总结,统计识别方法主要是简单相比与很多其它基于

机器学习的算法,本人总结了五种RGB色彩空间的统计算法源码如下:

Skin Filter1:

[java]  view plain copy
  1. public class SkinFilter1 extends AbstractBufferedImageOp {  
  2.   
  3.     @Override  
  4.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  5.         int width = src.getWidth();  
  6.         int height = src.getHeight();  
  7.   
  8.         if ( dest == null )  
  9.             dest = createCompatibleDestImage( src, null );  
  10.   
  11.         int[] inPixels = new int[width*height];  
  12.         int[] outPixels = new int[width*height];  
  13.         getRGB( src, 00, width, height, inPixels );  
  14.         int index = 0;  
  15.         for(int row=0; row<height; row++) {  
  16.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  17.             for(int col=0; col<width; col++) {  
  18.                 index = row * width + col;  
  19.                 ta = (inPixels[index] >> 24) & 0xff;  
  20.                 tr = (inPixels[index] >> 16) & 0xff;  
  21.                 tg = (inPixels[index] >> 8) & 0xff;  
  22.                 tb = inPixels[index] & 0xff;  
  23.                   
  24.                 // detect skin method...  
  25.                 double sum = tr + tg + tb;  
  26.                 if (((double)tr/(double)tb > 1.185) &&   
  27.                     ((double)(tr*tb)/(double)(sum*sum)>0.107) &&  
  28.                     ((double)(tr*tg)/(double)(sum*sum)>0.112))  
  29.                 {  
  30.                     tr = tg = tb = 0// black - skin detected!!  
  31.                 } else {  
  32.                     tr = tg = tb = 255// white color means non-skin pixel  
  33.                 }  
  34.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  35.             }  
  36.         }  
  37.         setRGB( dest, 00, width, height, outPixels );  
  38.         return dest;  
  39.     }  
  40. }  
Skin Filter2:

[java]  view plain copy
  1. public class SkinFilter2 extends AbstractBufferedImageOp {  
  2.   
  3.     @Override  
  4.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  5.         int width = src.getWidth();  
  6.         int height = src.getHeight();  
  7.   
  8.         if ( dest == null )  
  9.             dest = createCompatibleDestImage( src, null );  
  10.   
  11.         int[] inPixels = new int[width*height];  
  12.         int[] outPixels = new int[width*height];  
  13.         getRGB( src, 00, width, height, inPixels );  
  14.         int index = 0;  
  15.         for(int row=0; row<height; row++) {  
  16.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  17.             for(int col=0; col<width; col++) {  
  18.                 index = row * width + col;  
  19.                 ta = (inPixels[index] >> 24) & 0xff;  
  20.                 tr = (inPixels[index] >> 16) & 0xff;  
  21.                 tg = (inPixels[index] >> 8) & 0xff;  
  22.                 tb = inPixels[index] & 0xff;  
  23.                 double sum = tr + tg + tb;  
  24.                   
  25.                   
  26.                 if(((double)3*tb*tr*tr/(double)(sum*sum*sum)>0.1276)&&  
  27.                     ((double)(tr*tb+tg*tg)/(double)(tg*tb)>2.14)&&  
  28.                     ((double)(sum)/(double)(3*tr)+(double)(tr-tg)/(double)(sum)<2.7775))  
  29.                 {  
  30.                     tr = tg = tb = 0;  
  31.                 } else {  
  32.                     tr = tg = tb = 255;  
  33.                 }  
  34.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  35.             }  
  36.         }  
  37.         setRGB( dest, 00, width, height, outPixels );  
  38.         return dest;  
  39.     }  
  40. }  
Skin Filter3:

[java]  view plain copy
  1. public class SkinFilter3 extends AbstractBufferedImageOp {  
  2.   
  3.     @Override  
  4.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  5.         int width = src.getWidth();  
  6.         int height = src.getHeight();  
  7.   
  8.         if ( dest == null )  
  9.             dest = createCompatibleDestImage( src, null );  
  10.   
  11.         int[] inPixels = new int[width*height];  
  12.         int[] outPixels = new int[width*height];  
  13.         getRGB( src, 00, width, height, inPixels );  
  14.         int index = 0;  
  15.         for(int row=0; row<height; row++) {  
  16.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  17.             for(int col=0; col<width; col++) {  
  18.                 index = row * width + col;  
  19.                 ta = (inPixels[index] >> 24) & 0xff;  
  20.                 tr = (inPixels[index] >> 16) & 0xff;  
  21.                 tg = (inPixels[index] >> 8) & 0xff;  
  22.                 tb = inPixels[index] & 0xff;  
  23.                   
  24.                 // detect skin method...  
  25.                 double sum = tr + tg + tb;  
  26.                 if (((double)tg / (double)tg - (double)tr / (double)tb <= -0.0905) &&  
  27.                     ((double)(sum) / (double)(3 * tr) + (double)(tr - tg) / (double)(sum) <= 0.9498))  
  28.                 {  
  29.                     tr = tg = tb = 0;  
  30.                 } else {  
  31.                     tr = tg = tb = 255;  
  32.                 }  
  33.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  34.             }  
  35.         }  
  36.         setRGB( dest, 00, width, height, outPixels );  
  37.         return dest;  
  38.     }  
  39. }  
Skin Filter4:

[java]  view plain copy
  1. import java.awt.image.BufferedImage;  
  2. /** 
  3.  * this skin detection is absolutely good skin classification, 
  4.  * i love this one very much 
  5.  *  
  6.  * this one should be always primary skin detection  
  7.  * from all five filters 
  8.  *  
  9.  * @author zhigang 
  10.  * 
  11.  */  
  12. public class SkinFilter4 extends AbstractBufferedImageOp {  
  13.   
  14.     @Override  
  15.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  16.         int width = src.getWidth();  
  17.         int height = src.getHeight();  
  18.   
  19.         if ( dest == null )  
  20.             dest = createCompatibleDestImage( src, null );  
  21.   
  22.         int[] inPixels = new int[width*height];  
  23.         int[] outPixels = new int[width*height];  
  24.         getRGB( src, 00, width, height, inPixels );  
  25.         int index = 0;  
  26.         for(int row=0; row<height; row++) {  
  27.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  28.             for(int col=0; col<width; col++) {  
  29.                 index = row * width + col;  
  30.                 ta = (inPixels[index] >> 24) & 0xff;  
  31.                 tr = (inPixels[index] >> 16) & 0xff;  
  32.                 tg = (inPixels[index] >> 8) & 0xff;  
  33.                 tb = inPixels[index] & 0xff;  
  34.                   
  35.                 // detect skin method...  
  36.                 double sum = tr + tg + tb;  
  37.                 if (((double)tb/(double)tg<1.249) &&  
  38.                     ((double)sum/(double)(3*tr)>0.696) &&  
  39.                     (0.3333-(double)tb/(double)sum>0.014) &&  
  40.                     ((double)tg/(double)(3*sum)<0.108))  
  41.                 {  
  42.                     tr = tg = tb = 0;  
  43.                 } else {  
  44.                     tr = tg = tb = 255;  
  45.                 }  
  46.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  47.             }  
  48.         }  
  49.         setRGB(dest, 00, width, height, outPixels);  
  50.         return dest;  
  51.     }  
  52. }  
Skin Filter5:

[java]  view plain copy
  1. import java.awt.image.BufferedImage;  
  2. /** 
  3.  * this is very good skin detection 
  4.  * get real skin segmentation correctly.... 
  5.  * ohh... cool 
  6.  *  
  7.  * @author zhigang 
  8.  * 
  9.  */  
  10. public class SkinFilter5 extends AbstractBufferedImageOp {  
  11.   
  12.     @Override  
  13.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  14.         int width = src.getWidth();  
  15.         int height = src.getHeight();  
  16.   
  17.         if ( dest == null )  
  18.             dest = createCompatibleDestImage( src, null );  
  19.   
  20.         int[] inPixels = new int[width*height];  
  21.         int[] outPixels = new int[width*height];  
  22.         getRGB( src, 00, width, height, inPixels );  
  23.         int index = 0;  
  24.         for(int row=0; row<height; row++) {  
  25.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  26.             for(int col=0; col<width; col++) {  
  27.                 index = row * width + col;  
  28.                 ta = (inPixels[index] >> 24) & 0xff;  
  29.                 tr = (inPixels[index] >> 16) & 0xff;  
  30.                 tg = (inPixels[index] >> 8) & 0xff;  
  31.                 tb = inPixels[index] & 0xff;  
  32.                   
  33.                 // detect skin method...  
  34.                 double sum = tr + tg + tb;  
  35.                 if (((double)tg/(double)tb - (double)tr/(double)tg<=-0.0905)&&  
  36.                 ((double)(tg*sum)/(double)(tb*(tr-tg))>3.4857)&&  
  37.                 ((double)(sum*sum*sum)/(double)(3*tg*tr*tr)<=7.397)&&  
  38.                 ((double)sum/(double)(9*tr)-0.333 > -0.0976))  
  39.                 {  
  40.                     tr = tg = tb = 0;  
  41.                 } else {  
  42.                     tr = tg = tb = 255;  
  43.                 }  
  44.                 outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;  
  45.             }  
  46.         }  
  47.         setRGB( dest, 00, width, height, outPixels );  
  48.         return dest;  
  49.     }  
  50. }  
总结一下:

似乎Filter3的效果与Filter1的效果不是很好,Filter5, Filter4的效果感觉

还是很好的,基本上可以符合实际要求。

相关文章
|
3月前
|
编解码 算法 图形学
同一路RTSP|RTMP流如何同时回调YUV和RGB数据实现渲染和算法分析
我们播放RTSP|RTMP流,如果需要同时做渲染和算法分析的话,特别是渲染在上层实现(比如Unity),算法是python这种情况,拉两路流,更耗费带宽和性能,拉一路流,同时回调YUV和RGB数据也可以,但是更灵活的是本文提到的按需转算法期望的RGB数据,然后做算法处理
|
4月前
|
编解码 算法 Linux
Linux平台下RTSP|RTMP播放器如何跟python交互投递RGB数据供视觉算法分析
在对接Linux平台的RTSP播放模块时,需将播放数据同时提供给Python进行视觉算法分析。技术实现上,可在播放时通过回调函数获取视频帧数据,并以RGB32格式输出。利用`SetVideoFrameCallBackV2`接口设定缩放后的视频帧回调,以满足算法所需的分辨率。回调函数中,每收到一帧数据即保存为bitmap文件。Python端只需读取指定文件夹中的bitmap文件,即可进行视频数据的分析处理。此方案简单有效,但应注意控制输出的bitmap文件数量以避免内存占用过高。
|
4月前
|
算法
计算空间物体包围球的两种算法实现
计算空间物体包围球的两种算法实现
49 0
|
4月前
|
算法 C++
空间中判断点在三角形内算法(方程法)
空间中判断点在三角形内算法(方程法)
59 0
|
4月前
|
算法
空间点与直线距离算法
空间点与直线距离算法
55 0
|
4月前
|
算法 C++
空间直线与球面相交算法
空间直线与球面相交算法
32 0
|
4月前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
45 0
|
6月前
|
机器学习/深度学习 算法
五种基于RGB色彩空间统计的皮肤检测算法
五种基于RGB色彩空间统计的皮肤检测算法
41 0
|
2月前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
11天前
|
算法 数据安全/隐私保护 索引
OFDM系统PAPR算法的MATLAB仿真,对比SLM,PTS以及CAF,对比不同傅里叶变换长度
本项目展示了在MATLAB 2022a环境下,通过选择映射(SLM)与相位截断星座图(PTS)技术有效降低OFDM系统中PAPR的算法实现。包括无水印的算法运行效果预览、核心程序及详尽的中文注释,附带操作步骤视频,适合研究与教学使用。