正文涉及的很多算法,而自笔者代码里也壹度把简单的论断标准放在眼前

  
由于力量简单,算法层面包车型地铁事物本人去立异的很少,很多都以从现有的舆论中上学,然后实施的。

  在许多场地须要高效用的肤色检查测试代码,自个儿常用的三个C++版本的代码如下所示:

  在重重场面须要高效用的肤色检查实验代码,本人常用的多个C++版本的代码如下所示:

     
本文涉及的不少算法,在网络上也有为数不少同品种的小说,不过毫无疑问的有个别正是,很多都是不配代码的,可能所附带的代码都以象征性的,速度慢,不优雅,不有所实用价值,本文努力消除那么些题材。

void IM_GetRoughSkinRegion(unsigned char *Src, unsigned char *Skin, int Width, int Height, int Stride)
{
    for (int Y = 0; Y < Height; Y++)
    {
        unsigned char *LinePS = Src + Y * Stride;                    //    源图的第Y行像素的首地址
        unsigned char *LinePD = Skin + Y * Width;                    //    Skin区域的第Y行像素的首地址    for (int X = 0; X < Width; X++)
        for (int X = 0; X < Width; X++)
        {
            int Blue = LinePS[0], Green = LinePS[1], Red = LinePS[2];
            if (Red >= 60 && Green >= 40 && Blue >= 20 && Red >= Blue && (Red - Green) >= 10 && IM_Max(IM_Max(Red, Green), Blue) - IM_Min(IM_Min(Red, Green), Blue) >= 10)
                LinePD[X] = 255;                                    //    全为肤色部分                                                                            
            else
                LinePD[X] = 16;
            LinePS += 3;                                            //    移到下一个像素        
        }
    }
}
void IM_GetRoughSkinRegion(unsigned char *Src, unsigned char *Skin, int Width, int Height, int Stride)
{
    for (int Y = 0; Y < Height; Y++)
    {
        unsigned char *LinePS = Src + Y * Stride;                    //    源图的第Y行像素的首地址
        unsigned char *LinePD = Skin + Y * Width;                    //    Skin区域的第Y行像素的首地址    for (int X = 0; X < Width; X++)
        for (int X = 0; X < Width; X++)
        {
            int Blue = LinePS[0], Green = LinePS[1], Red = LinePS[2];
            if (Red >= 60 && Green >= 40 && Blue >= 20 && Red >= Blue && (Red - Green) >= 10 && IM_Max(IM_Max(Red, Green), Blue) - IM_Min(IM_Min(Red, Green), Blue) >= 10)
                LinePD[X] = 255;                                    //    全为肤色部分                                                                            
            else
                LinePD[X] = 16;
            LinePS += 3;                                            //    移到下一个像素        
        }
    }
}

     
文中各算法出现的顺序并不代表算法的优越性,仅仅是笔者随机排布的而已。

  那段代码功效的频率已经很高了,对于1080P含有人脸的形似图像大致也就肆.0ms就能处理完,效果嘛对江小鱼常光照和肤色的检验也还聚集,如下所示。

  那段代码功效的效能已经很高了,对于1080P含有人脸的形似图像大约也就4.0ms就能处理完,效果嘛对孙铎规光照和肤色的检验也还凑合,如下所示。

      一、1回多项式混合模型

      ca88亚洲城网站 1         
  ca88亚洲城网站 2

      ca88亚洲城网站 3         
  ca88亚洲城网站 4

          
二遍多项式混合模型首先有SO奥迪Q5IANO提议,此后CHIANG对此展开了改正。立异后的模子由七个汉兰达-G平面的一回多项式和二个圆方程构成:

     
四.0ms确实已经快捷了,不过在很多实时的场馆,每帧里能节省下来1MS对此全部的流畅性都以有利益的,那些算法还有未有提高速度的半空中吗。常规的C语言的方面包车型地铁优化大概也正是循环展开了吧,实地度量速度也没啥大的界别。

ca88亚洲城网站,     
肆.0ms确实已经急迅了,可是在许多实时的场子,每帧里能节省下来1MS对于全体的流畅性都是有实益的,这些算法还有未有升高速度的空中啊。常规的C语言的方面包车型大巴优化恐怕约等于循环展开了呢,实测速度也没啥大的分别。

      ca88亚洲城网站 5

     
那大家随后来品尝下SIMD指令会有何结果。

     
那大家跟着来尝试下SIMD指令会有如何结果。

  在上述多少个方程的底蕴上,肤色区域能够透过眨眼之间间平整完成:

     
在控制选择SIMD在此以前,作者一直在犹豫,因为这几个算法本人很简短的,正是1对口径判断组合,而SSE万分不相符于做判定运算,同时普通C语言的&&运算具有短路作用,对于本例,当发现中间之壹不符合条件后就平昔跳出了循环,不再进行末端的原则的计量和判断了,而本人代码里也早已把简单的判定标准放在眼下,复杂一点的放在前边了。纵然使用SSE去实现平等的成效,由于SSE的特征,大家只可以对拥有的口径举办判断,然后把各种条件判断的结果开始展览and操作,那个进程是心有余而力不足从中路中断的(从代码实现上说,是足以的,但是那种方式必定越来越慢)。那种周全判断的耗费时间和SSE处理器级别多路并行所带来的加快孰重孰轻,在尚未落到实处在此以前心里真的有点不明确。

     
在控制接纳SIMD以前,笔者直接在犹豫,因为这一个算法本人很简短的,就是有些尺码判断组合,而SSE非凡不适合于做判断运算,同时普通C语言的&&运算具有短路功能,对于本例,当发现里面之一不符合条件后就径直跳出了巡回,不再进行末端的尺度的盘算和判断了,而本身代码里也已经把大概的判定标准放在前边,复杂一点的位于后边了。假诺采取SSE去完结均等的效应,由于SSE的表征,大家只好对具备的规范实行判定,然后把每一种条件判断的结果实行and操作,那些进程是不能够从中间中断的(从代码完成上说,是可以的,然而那种办法必然更加慢)。那种周密判断的耗费时间和SSE处理器级别多路并行所推动的加速孰重孰轻,在未有落到实处此前心里真的有点不明确。

              ca88亚洲城网站 6 

   
既然写了本文,那肯定是曾经落到实处了该算法的SSE版本代码,我们的话为分析下达成的方法和可能用到的函数。 

   
既然写了本文,那一定是早已达成了该算法的SSE版本代码,大家来说为分析下促成的措施和大概用到的函数。 

     上述算法的参照散文:Adaptive skin
color modeling using the skin
locus.pdf  

     
首先,咱们要把汉兰达/G/B分量分别领取到一个SSE变量中,这么些大家在SSE图像算法优化种类8:自然饱和度(Vibrance)算法的上行下效完成及其SSE优化(附源码,可用作SSE图像入门,Vibrance算法也可用来不难的肤色调整) 一文里早就有关系了贯彻。

     
首先,大家要把奥迪Q3/G/B分量分别领取到贰个SSE变量中,这些大家在SSE图像算法优化类别八:自然饱和度(Vibrance)算法的邯郸学步完结及其SSE优化(附源码,可用作SSE图像入门,Vibrance算法也可用来简单的肤色调整) 一文里早就有涉及了落实。

            A novel method for detecting lips,eyes and faces
in real
time

      接着看后面包车型客车三个测量准则   Red >= 60 &&
格林 >= 40 && Blue >= 20 , 大家需求一个unsigned
char类型的比较函数,而SSE只提供了singed
char类型的SSE相比函数,这几个题材在A
few missing SSE intrinsics
 一文里有答案。能够用如下代码完结:

      接着看前边的七个测量圭表   Red >= 60 &&
格林 >= 40 && Blue >= 20 , 大家要求一个unsigned
char类型的可比函数,而SSE只提供了singed
char类型的SSE比较函数,那些标题在A
few missing SSE intrinsics
 一文里有答案。可以用如下代码达成:

  以及百度文库相关小说:依据混合肤色模型的神速人脸检查评定算法 

#define _mm_cmpge_epu8(a, b) _mm_cmpeq_epi8(_mm_max_epu8(a, b), a)
#define _mm_cmpge_epu8(a, b) _mm_cmpeq_epi8(_mm_max_epu8(a, b), a)

     上式中,小写r,g,b(未涉嫌)为对索罗德/G/B(byte类型的数码,0-255)举行归1化后的数额,即:

      第5个规格Red >= Blue
同样能够动用方面这一个判断来落到实处。

      第多少个原则Red >= Blue
同样能够利用方面这些判断来贯彻。

              ca88亚洲城网站 7

      大家再来看第五个条件(Red – 格林)
>= 十,即使一贯计算Red –
格林,则须要把他们更换为ushort类型才能满意恐怕存在的负数的气象,但是只要运用_mm_subs_epu八以此饱和计算函数,当Red
< 格林时,Red – Green就被截断为0了,那一年 (Red – 格林) >=
十就会回来false了,而只要Red > 格林, 则Red –
格林的结果就不会发出截断,正是上好的功效,由此,这些标题消除。

      我们再来看第四个标准化(Red – 格林)
>= 10,就算一向总结Red –
格林,则需求把他们更换为ushort类型才能满意大概存在的负数的景况,可是要是选择_mm_subs_epu捌这几个饱和总括函数,当Red
< Green时,Red – Green就被截断为0了,这年 (Red – 格林) >=
10就会回到false了,而只要Red > 格林, 则Red –
格林的结果就不会发生截断,正是杰出的作用,由此,这些题目化解。

     如上所示,算法中涉嫌到了重重的浮点运算,以及大气的乘法,假诺遵照源汁原味的来编排代码,程序的频率综上可得。因而,大家起始于算法的优化。

      最终一个标准IM_Max(IM_Max(Red,
Green), Blue) – IM_Min(IM_Min(Red, 格林), Blue) >=
十,这一个也很不难,先用_mm_max_epu8和_mm_min_epu八到手B/G/Odyssey三分量的最大值和微小值,这一年很醒目max>min,因而有能够一贯采纳_mm_subs_epu8函数生产不会截断的正确性结果。

      最终二个准绳IM_Max(IM_Max(Red,
Green), Blue) – IM_Min(IM_Min(Red, 格林), Blue) >=
10,那一个也很简短,先用_mm_max_epu8和_mm_min_epu八赢得B/G/CR-V三分量的最大值和纤维值,这一年很醒目max>min,由此有能够一直运用_mm_subs_epu八函数生产不会截断的不易结果。

     首先,大家来看八个评定准则,由于衡量圭臬是不分先后,须要同时满足的地点才是区域,由此应当把差不多的判定标准放在最后面判断。

     
大家注意到SSE的可比函数(字节类型的)的回到结果只有0和255那二种,因而上述的两个测量标准结果一向开始展览and操作就能够取得最终的组合值了,满足全数的基准的像素结果就为25五,而别的的则为0。

     
大家注意到SSE的可比函数(字节类型的)的归来结果唯有0和25伍那两种,由此上述的四个测量规范结果从来开始展览and操作就可以得到最终的组合值了,满足全数的口径的像素结果就为255,而任何的则为0。

     首先看假如符合了判断条件奥迪Q54,条件R3中的Highlander>G肯定是1度成立的,则只供给判断G是还是不是高于B,那是优化手段1。   

     
在我们C语言版本的代码中,不满意条件的像素被安装为了16恐怕别的非零的值,这又如何是好吧,同样的道理,255和别的数进行or操作依然25五,而0和别的数举办or操作就会成为其余数,因而最后再把上述结果和16那几个常数举行or操作就足以拿走不错的结果了,整理下来,首要代码如下所示:

     
在大家C语言版本的代码中,不满意条件的像素被设置为了16要么别的非零的值,那又如何是好吧,同样的道理,25五和任何数实行or操作依然255,而0和别的数举办or操作就会化为别的数,因而最终再把上述结果和1陆那个常数实行or操作就足以获取不错的结果了,整理下来,首要代码如下所示:

    
然后大家来看LX5702的优化,为便利表明,大家这里令Sum=汉兰达+G+B,将判断条件奥德赛2展开:

Src1 = _mm_loadu_si128((__m128i *)(LinePS + 0));
Src2 = _mm_loadu_si128((__m128i *)(LinePS + 16));
Src3 = _mm_loadu_si128((__m128i *)(LinePS + 32));

Blue = _mm_shuffle_epi8(Src1, _mm_setr_epi8(0, 3, 6, 9, 12, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
Blue = _mm_or_si128(Blue, _mm_shuffle_epi8(Src2, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, 2, 5, 8, 11, 14, -1, -1, -1, -1, -1)));
Blue = _mm_or_si128(Blue, _mm_shuffle_epi8(Src3, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 4, 7, 10, 13)));

Green = _mm_shuffle_epi8(Src1, _mm_setr_epi8(1, 4, 7, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
Green = _mm_or_si128(Green, _mm_shuffle_epi8(Src2, _mm_setr_epi8(-1, -1, -1, -1, -1, 0, 3, 6, 9, 12, 15, -1, -1, -1, -1, -1)));
Green = _mm_or_si128(Green, _mm_shuffle_epi8(Src3, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 5, 8, 11, 14)));

Red = _mm_shuffle_epi8(Src1, _mm_setr_epi8(2, 5, 8, 11, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
Red = _mm_or_si128(Red, _mm_shuffle_epi8(Src2, _mm_setr_epi8(-1, -1, -1, -1, -1, 1, 4, 7, 10, 13, -1, -1, -1, -1, -1, -1)));
Red = _mm_or_si128(Red, _mm_shuffle_epi8(Src3, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 6, 9, 12, 15)));

Max = _mm_max_epu8(_mm_max_epu8(Blue, Green), Red);                                                //    IM_Max(IM_Max(Red, Green), Blue)
Min = _mm_min_epu8(_mm_min_epu8(Blue, Green), Red);                                                //    IM_Min(IM_Min(Red, Green), Blue)
Result = _mm_cmpge_epu8(Blue, _mm_set1_epi8(20));                                                //    Blue >= 20
Result = _mm_and_si128(Result, _mm_cmpge_epu8(Green, _mm_set1_epi8(40)));                        //    Green >= 40
Result = _mm_and_si128(Result, _mm_cmpge_epu8(Red, _mm_set1_epi8(60)));                            //    Red >= 60
Result = _mm_and_si128(Result, _mm_cmpge_epu8(Red, Blue));                                        //  Red >= Blue
Result = _mm_and_si128(Result, _mm_cmpge_epu8(_mm_subs_epu8(Red, Green), _mm_set1_epi8(10)));    //    (Red - Green) >= 10 
Result = _mm_and_si128(Result, _mm_cmpge_epu8(_mm_subs_epu8(Max, Min), _mm_set1_epi8(10)));        //    IM_Max(IM_Max(Red, Green), Blue) - IM_Min(IM_Min(Red, Green), Blue) >= 10
Result = _mm_or_si128(Result, _mm_set1_epi8(16));
_mm_storeu_si128((__m128i*)(LinePD + 0), Result);
Src1 = _mm_loadu_si128((__m128i *)(LinePS + 0));
Src2 = _mm_loadu_si128((__m128i *)(LinePS + 16));
Src3 = _mm_loadu_si128((__m128i *)(LinePS + 32));

Blue = _mm_shuffle_epi8(Src1, _mm_setr_epi8(0, 3, 6, 9, 12, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
Blue = _mm_or_si128(Blue, _mm_shuffle_epi8(Src2, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, 2, 5, 8, 11, 14, -1, -1, -1, -1, -1)));
Blue = _mm_or_si128(Blue, _mm_shuffle_epi8(Src3, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 4, 7, 10, 13)));

Green = _mm_shuffle_epi8(Src1, _mm_setr_epi8(1, 4, 7, 10, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
Green = _mm_or_si128(Green, _mm_shuffle_epi8(Src2, _mm_setr_epi8(-1, -1, -1, -1, -1, 0, 3, 6, 9, 12, 15, -1, -1, -1, -1, -1)));
Green = _mm_or_si128(Green, _mm_shuffle_epi8(Src3, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 5, 8, 11, 14)));

Red = _mm_shuffle_epi8(Src1, _mm_setr_epi8(2, 5, 8, 11, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1));
Red = _mm_or_si128(Red, _mm_shuffle_epi8(Src2, _mm_setr_epi8(-1, -1, -1, -1, -1, 1, 4, 7, 10, 13, -1, -1, -1, -1, -1, -1)));
Red = _mm_or_si128(Red, _mm_shuffle_epi8(Src3, _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, 6, 9, 12, 15)));

Max = _mm_max_epu8(_mm_max_epu8(Blue, Green), Red);                                                //    IM_Max(IM_Max(Red, Green), Blue)
Min = _mm_min_epu8(_mm_min_epu8(Blue, Green), Red);                                                //    IM_Min(IM_Min(Red, Green), Blue)
Result = _mm_cmpge_epu8(Blue, _mm_set1_epi8(20));                                                //    Blue >= 20
Result = _mm_and_si128(Result, _mm_cmpge_epu8(Green, _mm_set1_epi8(40)));                        //    Green >= 40
Result = _mm_and_si128(Result, _mm_cmpge_epu8(Red, _mm_set1_epi8(60)));                            //    Red >= 60
Result = _mm_and_si128(Result, _mm_cmpge_epu8(Red, Blue));                                        //  Red >= Blue
Result = _mm_and_si128(Result, _mm_cmpge_epu8(_mm_subs_epu8(Red, Green), _mm_set1_epi8(10)));    //    (Red - Green) >= 10 
Result = _mm_and_si128(Result, _mm_cmpge_epu8(_mm_subs_epu8(Max, Min), _mm_set1_epi8(10)));        //    IM_Max(IM_Max(Red, Green), Blue) - IM_Min(IM_Min(Red, Green), Blue) >= 10
Result = _mm_or_si128(Result, _mm_set1_epi8(16));
_mm_storeu_si128((__m128i*)(LinePD + 0), Result);

                ca88亚洲城网站 8     

  循环总括九十九回的进程测试:

  循环总括玖十八次的进程测试:

     上架子最终一步同时乘以156,
理论上说15陆×0.3三=5壹.4八,不该取5二的,可是这么些0.3三理所当然正是个经验数据,哪个人说无法是1/三吗。

环境

1920*1080 肤色约占一半图

1920*1080 全图肤色

1920*1080 全图无肤色

标准C语言

 400ms

 550ms

360ms 

SSE优化

 70ms

 70ms

70ms 

环境

1920*1080 肤色约占一半图

1920*1080 全图肤色

1920*1080 全图无肤色

标准C语言

 400ms

 550ms

360ms 

SSE优化

 70ms

 70ms

70ms 

     到此,咱们看出在架子的最右面还有个浮点数0.06贰四,假使不拔除该数量,算法速度依然会有大的熏陶,常常商讨活动的爱人一定对0.06二伍以此数字很纯熟,1/1陆=0.06二伍,不是吗,懂了啊,还不懂,看代码吧(这里的姿势很多都以涉世公式,由此,稍微修改部分参数对结果基本无影响)。

 

 

    
上述如此做的目标,无非是将浮点数的运算全体转换为整数的演算。

 

 

  最终来看式Escort1的优化,R1骨子里也是多少个条件,把他分开来,分小名为Lacrosse11及R12,对于R11,同样举办:

  

  

                ca88亚洲城网站 9

     

     

     以后超过陆一%的PC都照旧三10个人的体系,由此,使用三十五位的整数类数据类型速度是最快的,因而,倘使上述放大周到的取夺就亟须珍视使得总结式两边的值都在int.MinValue和
int.马克斯Value之间,比如上式,>号左边算式的肯能最大取值为一千0×25伍×765,是低于int.马克斯Value所能表明的限定的,由此放大周全是客观的。

   
 能够观望,尽管SSE优化后的总计量理论上比一般的C语言大过多,不过SSE优化的算法有多个好处,第3是速度快很多,最大加快比约有八倍了,第一是SSE的乘除时间和图像内容是文不对题的。

   
 能够看到,尽管SSE优化后的计算量理论上比平时的C语言大过多,可是SSE优化的算法有多个好处,第3是速度快很多,最大加快比约有8倍了,第2是SSE的计算时间和图像内容是井水不犯河水的。

    
对于R12的进展小编想应该不必要自家在去贴出来了呢。

   
 那一个结果令本人大为震惊,看样子SSE一次性处理17个字节的力量不是盖的,同时也印证普通的C语言的跳转也依然耗费时间的。

   
 那几个结果令自个儿大为震惊,看样子SSE3次性处理15个字节的力量不是盖的,同时也验证普通的C语言的跳转也如故耗费时间的。

     算法部分参考代码:

   
 完整工程的地址:http://files.cnblogs.com/files/Imageshop/GetSkinArea.rar

   
 完整工程的地方:http://files.cnblogs.com/files/Imageshop/GetSkinArea.rar

for (Y = 0; Y < Height; Y++)
{
    Pointer = Scan0 + Y * Stride;
    SkinP = SkinScan0 + Y * SkinStride;
    for (X = 0; X < Width; X++)
    {
        *SkinP = 0;                                 // 非皮肤区域为黑色

        Blue = *Pointer; Green = *(Pointer + 1); Red = *(Pointer + 2);
        if (Red - Green >= 45)                                              //  符合条件R4
        {
            if (Green > Blue)                                               //   符合条件R3
            {
                Sum = Red + Green + Blue;
                T1 = 156 * Red - 52 * Sum;                                 
                T2 = 156 * Green - 52 * Sum;
                if (T1 * T1 + T2 * T2 >= (Sum * Sum) >> 4)                    // 符合条件R2,在32位系统要尽量避免用long类型数据,
                   {
                    T1 = 10000 * Green * Sum;
                    Lower = - 7760 * Red * Red + 5601 * Red * Sum + 1766 * Sum * Sum;         // 把这里的公用的乘法提取出来基本没啥优化的效果
                        if (T1 > Lower)                                         // 符合条件R11
                    {
                        Upper = - 13767 * Red * Red + 10743 * Red * Sum + 1452 * Sum * Sum ;
                        if (T1 < Upper)                                     //  符合条件R12
                        {
                            *SkinP = 255;
                     }
                    }
                }
            }
        }
        Pointer += 3;
        SkinP++;
    }

   
 结合肤色检查测试以及从前研讨的积分图、均方差去噪等算法,笔者用纯SSE写了二个归纳的MakeUp算法,处理单帧的拾80P的图像用时大致也就在二伍ms内完结(单核),比纯C语言的要快了叁到四倍,如下图所示:

   
 结合肤色检查实验以及以前钻探的积分图、均方差去噪等算法,笔者用纯SSE写了3个综合的MakeUp算法,处理单帧的十80P的图像用时大致也就在25ms内完毕(单核),比纯C语言的要快了三到肆倍,如下图所示:

  本人特喜欢优化,尤其是代码层面包车型大巴优化,比如上述的 Lower = 560一 * Red
* Sum + 1766 * Sum * Sum 这句,偶尔小编写成Lower =- Red * Red * 7760+
5601 * Red * Sum + 1766 * Sum * Sum
那样,然后没事的时候作者反汇编了三种写法有啥样分化,结果如下:

ca88亚洲城网站 10

ca88亚洲城网站 11

 Lower =-7760 * Red * Red+ 5601 * Red * Sum + 1766 * Sum * Sum ;         // 把这里的公用的乘法提取出来基本没啥优化的效果
00000118  imul        ebx,ecx,0FFFFE1B0h 
0000011e  imul        ebx,ecx 
00000121  imul        eax,ecx,15E1h 
00000127  imul        eax,esi 
0000012a  add         ebx,eax 
0000012c  imul        eax,esi,6E6h 
00000132  imul        eax,esi 
00000135  add         ebx,eax 

   http://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar,这里是3个小编全方位用SSE优化的图像处理的德姆o,有趣味的恋人能够看看。

   http://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar,那里是五个本人整整用SSE优化的图像处理的德姆o,有趣味的敌人能够看看。

 

ca88亚洲城网站 12

ca88亚洲城网站 13

 Lower = -Red * Red * 7760 * +5601 * Red * Sum + 1766 * Sum * Sum;         // 把这里的公用的乘法提取出来基本没啥优化的效果
00000118  mov         ebx,ecx 
0000011a  neg         ebx 
0000011c  imul        ebx,ecx 
0000011f  imul        ebx,ebx,1E50h 
00000125  imul        ebx,ebx,15E1h 
0000012b  imul        ebx,ecx 
0000012e  imul        ebx,esi 
00000131  imul        eax,esi,6E6h 
00000137  imul        eax,esi 
0000013a  add         ebx,eax 

 

 

     可知多了两条汇编语句的。只怕这几个优化举在此间不体面,因为有个周到-7760,一般什么人都不会像上面写,但是借使全面是-壹,那就比肯定了,比如若是是-Red+Blue
和Blue-Red那就有着完全不一致的含义了。

     
这几个算法的皮肤检验效果还是很科学的,那原来的书文中的图像来比喻如下:

    ca88亚洲城网站 14 
   ca88亚洲城网站 15   
ca88亚洲城网站 16

            
原图                                                           梦版图                                                     
合成图

 然后贴一张别人博客上的相片的例子(一批美男子和红颜):

ca88亚洲城网站 17

 检验结果:

ca88亚洲城网站 18

   由于是有选择性的推行,因而程序执行的进程其实和图像的内容关于,同样壹副大小的图像,假设皮肤部分站的比例越大,执行的小时大概就会越长,就上述那幅800*600的图像来说,在自个儿I三的台式机上仅用了四ms就获得了结果,由此进程是一对1的快的。

     

 

***************************笔者:
laviewpbt   时间: 20一3.八.一七   联系QQ:  33184777 转发请保留本行音信*************************

 

 

 

 

相关文章