为什么要追寻更快的高斯平滑速度?(比IIR高斯递归法还快,c#实现,二)

你也可以用c++,sse优化,效率更高。

这个是算法:

SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现)。 - Imageshop - 博客园 (cnblogs.com)

这个是原理:

gauss - 道客巴巴 (doc88.com)

我翻译的c#代码如下(超高速高斯平滑):

void Blur(byte[] Src, byte[] Dest, int Width, int Height,int Radius)
  {//50ms//不调用的话,更快
     
      if ((Src == null) || (Dest == null))                    return ;
      if ((Width <= 0) || (Height <= 0) || (Radius <= 0))        return ;
     if (Radius < 1)                                            return ;
   
  
    //  Radius = Height - 1;        //    由于镜像的需求,要求半径不能大于宽度或高度-1的数据
  
     int SampleAmount = (2 * Radius + 1) * (2 * Radius + 1);
     float Inv = 1.0f / SampleAmount;
  
    int []ColValue = new int[Width + Radius + Radius ];
      int []ColOffset = new int[Height + Radius + Radius];
   /* if ((ColValue == NULL) || (ColOffset == NULL))
      {
        if (ColValue != NULL)    free(ColValue);
       if (ColOffset != NULL)    free(ColOffset);
        return IM_STATUS_OUTOFMEMORY;
      }*/
      for (int Y = 0; Y < Height + Radius + Radius; Y++)
         ColOffset[Y] = imgetmirrorpos(Height, Y - Radius);

   
          for (int Y = 0; Y < Height; Y++)
        {
              //unsigned char *LinePD = Dest + Y * Width;
              
            if (Y == 0)
            {
               //  memset(ColValue + Radius, 0, Width * sizeof(int));
               

               for (int Z = -Radius; Z <= Radius; Z++)
                 {
                     // unsigned char *LinePS = Src + ColOffset[Z + Radius] * Width;
                  
                    for (int X = 0; X < Width; X++)
                    {
                         //ColValue[X + Radius] += LinePS[X];                                            //    更新列数据
                         ColValue[X + Radius] +=  Src[ColOffset[Z + Radius] * Width+X]; 
                   }
               }
            }
              else
            {
               // unsigned char *RowMoveOut = Src + ColOffset[Y - 1] * Width;                //    即将减去的那一行的首地址    
           //    unsigned char *RowMoveIn = Src + ColOffset[Y + Radius + Radius] * Width;    //    即将加上的那一行的首地址
                for (int X = 0; X < Width; X++)
                {
                    //ColValue[X + Radius] -= RowMoveOut[X] - RowMoveIn[X];                                            //    更新列数据
                     ColValue[X + Radius] -= Src[ColOffset[Y - 1] * Width+X] - Src[ ColOffset[Y + Radius + Radius] * Width+X];      
                }
            }
            FillLeftAndRight_Mirror_C(ColValue, Width, Radius);                //    镜像填充左右数据
            int LastSum = SumofArray_C(ColValue, Radius * 2 + 1);                //    处理每行第一个数据  
              
             //  byte LinePD = Dest [Y * Width];  
            //LinePD[0] = IM_ClampToByte(LastSum * Inv);
                 Dest [Y * Width]= IM_ClampToByte((int)(LastSum * Inv));
            for (int X = 1; X < Width; X++)
            {
                int NewSum = LastSum - ColValue[X - 1] + ColValue[X + Radius + Radius];
               Dest [Y * Width+X]= IM_ClampToByte((int)(NewSum * Inv));
               LastSum = NewSum;
            }
        }

}

///相关调用函数如下:

  int imgetmirrorpos(int length,int pos)
{
    if(pos<0)
        return -pos;
    else if(pos>=length)
        return length*2-pos-2;
    else
        return pos;
}
void FillLeftAndRight_Mirror_C(int []Array, int Length, int Radius)
  {
      for (int X = 0; X < Radius; X++)
      {
         Array[X] = Array[Radius + Radius - X];
        Array[Radius + Length + X] = Array[Radius + Length - X - 2];
      }
 }
 int SumofArray_C(int []Array, int Length)
 {
    int Sum = 0;
      for (int X = 0; X < Length; X++)
     {
         Sum += Array[X];
      }
     return Sum;
 }
  byte IM_ClampToByte(int Value)         
 {
    if (Value < 0)
        return 0;
    else if (Value > 255)
        return 255;
     else
        return (byte)Value;
    //return ((Value | ((signed int)(255 - Value) >> 31)) & ~((signed int)Value >> 31));
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值