C++ 高斯模糊不均匀

C++ 高斯模糊不均匀,c++,image-processing,gaussian,C++,Image Processing,Gaussian,我一直在尝试为我的图像编辑程序实现一个简单的高斯模糊算法。然而,我在这方面遇到了一些困难,我认为问题在于以下片段: for( int j = 0; j < pow( kernel_size, 2 ); j++ ) { int idx = ( i + kx + ( ky * img.width )); //Try and overload this whenever possible v

我一直在尝试为我的图像编辑程序实现一个简单的高斯模糊算法。然而,我在这方面遇到了一些困难,我认为问题在于以下片段:

        for( int j = 0; j < pow( kernel_size, 2 ); j++ )
        {
            int idx = ( i + kx + ( ky * img.width ));

            //Try and overload this whenever possible
            valueR += ( img.p_pixelArray[ idx ].r * kernel[ j ] );
            valueG += ( img.p_pixelArray[ idx ].g * kernel[ j ] );
            valueB += ( img.p_pixelArray[ idx ].b * kernel[ j ] );

            if( kx == kernel_limit )
            {
                kx = -kernel_limit;
                ky++;
            }

            else    
            {
                kx++;
            }
       }

       kx = -kernel_limit;
       ky = -kernel_limit;
所以我可以让kx从-1(一个3x3内核)变为+1,对于ky也是一样。我认为问题在于行

int idx = ( i + kx + ( ky * img.width ));
但我不确定。我得到的印象是:

可以看出,颜色在对角线方向上模糊,看起来更像某种运动模糊,而不是高斯模糊。如果有人能帮忙,我将非常感激

编辑: 我填充内核的方式如下所示:

for( int i = 0; i < pow( kernel_size, 2 ); i++ )
{
    // This. Is. Lisp.
    kernel[i] = (( 1 / ( 2 * pi * pow( sigma, 2 ))) * pow (e, ( -((( pow( kx, 2 ) + pow( ky, 2 )) / 2 * pow( sigma, 2 ))))));

    if(( kx + 1 ) == kernel_size )
    {
        kx = 0;
        ky++;
    }

    else
    {
        kx++;
    }
}
for(inti=0;i
几个问题:

2*pow(sigma,2)
附近,你的高斯函数忽略了括号(即使你已经有很多…)。现在用方差相乘,而不是除法

但是你的问题是,你的高斯分布集中在
kx=ky=0
,当你让它从
0
运行到
kernel\u size
,而不是从
-kernel\u limit
运行到
kernel\u limit
。这会导致对角线模糊。像下面这样的方法应该会更好

kx = -kernel_limit;
ky = -kernel_limit;

int kernel_size_sq = kernel_size * kernel_size;

for( int i = 0; i < kernel_size_sq; i++ )
{
  double sigma_sq = sigma * sigma;
  double kx_sq = kx * kx;
  double ky_sq = ky * ky;
  kernel[i] =  1.0 / ( 2 * pi * sigma_sq) * exp(-(kx_sq + ky_sq) / (2 * sigma_sq));

  if(kx == kernel_limit )
  {
    kx = -kernel_limit;
    ky++;
  }
  else
  {
    kx++;
  }
}
kx=-kernel\u limit;
ky=-核极限;
int kernel_size_sq=kernel_size*kernel_size;
for(int i=0;i

还要注意我是如何摆脱你们的lisp语言的,还有一些改进:为了清晰起见,使用一些中间变量(若你们要求编译器优化的话,编译器会把它们优化掉);简单乘法比pow(x,2)
pow(e,x)=exp(x)

我想最后两个语句应该在你的循环之外?否则,每次迭代都会覆盖
kx
ky
,而
idx
的值总是相同的。另外,你能展示一下你是如何填充
内核的
,也许这就是问题所在。哦,是的,不管怎样,它们都在循环之外,我只是把它们放在了错误的地方…@sgvd编辑了这个问题,将内核计算包括在内。
kx = -kernel_limit;
ky = -kernel_limit;

int kernel_size_sq = kernel_size * kernel_size;

for( int i = 0; i < kernel_size_sq; i++ )
{
  double sigma_sq = sigma * sigma;
  double kx_sq = kx * kx;
  double ky_sq = ky * ky;
  kernel[i] =  1.0 / ( 2 * pi * sigma_sq) * exp(-(kx_sq + ky_sq) / (2 * sigma_sq));

  if(kx == kernel_limit )
  {
    kx = -kernel_limit;
    ky++;
  }
  else
  {
    kx++;
  }
}