图像算法---头发检测算法研究

最近在做头发检测的算法研究,在此做个总结。

发色检测目前主要的方法有:1,基于颜色空间统计的发色检测;2,基于概率模型、高斯模型的发色检测;3,基于神经网络机器学习的发色检测;

这三种方法中,最稳定的是第3种,但是该方法实现起来比较复杂,样本量大;最简单的是第1种,但是不精确;

说实在的,这三种方法,都没办法完美检测发色,也就是没办法避开同色的干扰,不过,今天本人还是要介绍一种,相对来讲,比较实用的方法:

本文的算法使用最简单的颜色空间模型和概率模型,参考文献为:《Hair color modeling and head detection》,在此文献基础上修改而成。

为了便于理解,本文直接介绍算法实现过程,相信大家对于没用的也不太想看呵呵,因此,对于理论,大家没兴趣的可以跳过。

理论基础:

1,基于YCbCr颜色空间,对N个头发区域像素进行 采样统计,结果如下图:


2,将统计结果投影在Cb-Cr平面,结果如下:


3,采用高斯混合概率模型对发色的色度概率分布进行描述:



4,根据Cb和Cr的取值范围对当前像素进行肤色判断:

                                                   if(Cb<=141&&Cb>=115&&Cr>=115&&Cr<=143)

                                                                            P(i,j)为发色

                                                   else

                                                                            P(i,j)非发色

上面1-4的过程即论文《Hair color modeling and head detection》中所介绍的方法,测试效果如下:



经过我的测试,论文中的方法检测准确率很低,这里简单放上两张测试图,大家可以看到,误检率很高,把较多的背景和肤色都检测成了发色。

因此,本人对这个算法进行了改进,添加了一个约束条件:

由于发色主要是黑色为主,偏黄或者偏白,这几种情况都跟RGB三分量中的R分量关系最密切,因此,本人添加了R约束:R<Th

Th是经验值,这里我们实际使用中可以使用Th=60,这个值是我测试N张图的到的经验值,同时,也可以使用动态调节Th来获取发色区域,这里我

给出几张测试效果:


大家可以从效果上看出,改进的方法效果很不错,呵呵,最后改进后的判断条件如下:

                                                   if(Cb<=141&&Cb>=115&&Cr>=115&&Cr<=143&&R<Th)

                                                                            P(i,j)为发色

                                                   else

                                                                            P(i,j)非发色

                                                    默认值Th = 60

这里,给出C#代码如下:

        public Bitmap HairD(Bitmap src, int k )
        {
            Bitmap a = new Bitmap(src);
            Rectangle rect = new Rectangle(0, 0, a.Width, a.Height);
            System.Drawing.Imaging.BitmapData bmpData = a.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            int stride = bmpData.Stride;
            unsafe
            {
                byte* pIn = (byte*)bmpData.Scan0.ToPointer();
                byte* p;
                int R, G, B;
                double Cr, Cb, BrightV;
                for (int y = 0; y < a.Height; y++)
                {
                    for (int x = 0; x < a.Width; x++)
                    {
                        p = pIn;
                        R = p[2];
                        G = p[1];
                        B = p[0];
                        Cb = 128 - 37.797 * R / 255 - 74.203 * G / 255 + 112 * B / 255;
                        Cr = 128 + 112 * R / 255 - 93.768 * G / 255 - 18.214 * B / 255;
                        if (!(Cb >= 115 && Cb <= 141 && Cr >= 115 && Cr <= 143&&R<k))
                        {
                            pIn[0] = (byte)255;
                            pIn[1] = (byte)255;
                            pIn[2] = (byte)255;
                        }
                        pIn += 3;

                    }
                    pIn += stride - a.Width * 3;
                }
            }
            a.UnlockBits(bmpData);
            return a;
        }

最后,放上一个DEMO,下载地址: 点击打开链接




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Trent1985

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值