优化浮动模糊变化 [英] Optimized float Blur variations

查看:184
本文介绍了优化浮动模糊变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在c ++中寻找优化函数来计算浮点数的面积平均值。该函数传递一个源浮点数组,一个目标float数组(与源数组相同的大小),数组宽度和高度,模糊区域宽度和高度。

I am looking for optimized functions in c++ for calculating areal averages of floats. the function is passed a source float array, a destination float array (same size as source array), array width and height, "blurring" area width and height.

这里是使用矩形形状模糊的示例代码:

Here is example code that blur with a rectangular shape:

/*****************************************
*   Find averages extended variations
*****************************************/

void findaverages_ext(float *floatdata, float *dest_data, int fwidth, int fheight, int scale, int aw, int ah, int weight, int xoff, int yoff)
{
printf("findaverages_ext scale: %d, width: %d, height: %d, weight: %d \n", scale, aw, ah, weight);

float total = 0.0;
int spos = scale * fwidth * fheight;
int apos;

int w = aw;
int h = ah;

float* f_temp       = new float[fwidth * fheight];

// Horizontal
for(int y=0;y<fheight   ;y++)
{
    Sleep(10);      // Do not burn your processor 

    total = 0.0;

    // Process entire window for first pixel (including wrap-around edge)
    for (int kx = 0; kx <= w; ++kx)
        if (kx >= 0 && kx < fwidth)
            total += floatdata[y*fwidth + kx];
    // Wrap
    for (int kx = (fwidth-w); kx < fwidth; ++kx)
        if (kx >= 0 && kx < fwidth)
            total += floatdata[y*fwidth + kx];

    // Store first window
    f_temp[y*fwidth] = (total / (w*2+1));

    for(int x=1;x<fwidth    ;x++)           // x width changes with y
    {
        // Substract pixel leaving window
        if (x-w-1 >= 0)
            total -= floatdata[y*fwidth + x-w-1];

        // Add pixel entering window
        if (x+w < fwidth)
            total += floatdata[y*fwidth + x+w];
        else
            total += floatdata[y*fwidth + x+w-fwidth];

        // Store average
        apos = y * fwidth + x;
        f_temp[apos] = (total / (w*2+1));
    }
}


// Vertical
for(int x=0;x<fwidth    ;x++)
{
    Sleep(10);      // Do not burn your processor 

    total = 0.0;

    // Process entire window for first pixel
    for (int ky = 0; ky <= h; ++ky)             
        if (ky >= 0 && ky < fheight)
            total += f_temp[ky*fwidth + x];
    // Wrap
    for (int ky = fheight-h; ky < fheight; ++ky)                
        if (ky >= 0 && ky < fheight)
            total += f_temp[ky*fwidth + x];

    // Store first if not out of bounds
    dest_data[spos + x] = (total / (h*2+1));

    for(int y=1;y< fheight  ;y++)           // y width changes with x
    {
        // Substract pixel leaving window
        if (y-h-1 >= 0)
            total -= f_temp[(y-h-1)*fwidth + x];

        // Add pixel entering window
        if (y+h < fheight)
            total += f_temp[(y+h)*fwidth + x];
        else
            total += f_temp[(y+h-fheight)*fwidth + x];

        // Store average
        apos = y * fwidth + x;
        dest_data[spos+apos] = (total / (h*2+1));
    }
}

delete f_temp;
}

我需要的是类似的功能,

What I need is similar functions that for each pixel finds the average (blur) of pixels from shapes different than rectangular.

具体形状有:S(尖锐边缘),O(矩形但空心),+ X,其中平均浮点存储在目的数据阵列上的中心像素处。模糊形状的大小应该是可变的,宽度和高度。

The specific shapes are: "S" (sharp edges), "O" (rectangular but hollow), "+" and "X", where the average float is stored at the center pixel on destination data array. Size of blur shape should be variable, width and height.

这些函数不需要是pixelperfect,只针对性能进行了优化。每个形状可以有单独的函数。

The functions does not need to be pixelperfect, only optimized for performance. There could be separate functions for each shape.

我也很高兴,如果任何人可以提示我如何优化上面的示例函数为rectangluar模糊。

I am also happy if anyone can tip me of how to optimize the example function above for rectangluar blurring.

推荐答案

您要实现的是各种用于图像处理的数字滤波器。这相当于卷积两个信号,其中第二个将是滤波器的脉冲响应。到目前为止,您已经认识到矩形平均是可分离的。 可分隔我的意思是,您可以将过滤器拆分为两部分。一个沿着X轴运行,另一个沿着Y轴运行 - 在每种情况下都是1D滤波器。这是很好的,可以节省你很多的周期。但并非每个过滤器都是可分离的。 沿其他形状(S,O,+,X)的平均是不可分离的。您需要为这些计算实际的2D卷积。

What you are trying to implement are various sorts of digital filters for image processing. This is equivalent to convolving two signals where the 2nd one would be the filter's impulse response. So far, you regognized that a "rectangular average" is separable. By separable I mean, you can split the filter into two parts. One that operates along the X axis and one that operates along the Y axis -- in each case a 1D filter. This is nice and can save you lots of cycles. But not every filter is separable. Averaging along other shapres (S, O, +, X) is not separable. You need to actually compute a 2D convolution for these.

至于性能,您可以通过正确实施移动平均加快您的1D平均值。适当的移动平均实现仅需要每个像素固定量的小量工作,而不管平均窗口。这可以通过识别目标图像的相邻像素由几乎相同像素的平均值计算来完成。您可以通过添加一个新的像素强度并减去较旧的像素强度(对于1D情况),来重复使用这些和值。

As for performance, you can speed up your 1D averages by properly implementing a "moving average". A proper "moving average" implementation only requires a fixed amount of little work per pixel regardless of the averaging "window". This can be done by recognizing that neighbouring pixels of the target image are computed by an average of almost the same pixels. You can reuse these sums for the neighbouring target pixel by adding one new pixel intensity and subtracting an older one (for the 1D case).

在任意不可分离的情况下过滤你最好的投注性能是快速卷积,这是基于FFT。结帐www.dspguide.com。如果我记得正确,甚至有一章关于如何使用FFT算法正确做快速卷积。虽然,他们解释它为1维信号,它也适用于2维信号。对于图像,您必须执行2D-FFT / iFFT变换。

In case of arbitrary non-separable filters your best bet performance-wise is "fast convolution" which is FFT-based. Checkout www.dspguide.com. If I recall correctly, there is even a chapter on how to properly do "fast convolution" using the FFT algorithm. Although, they explain it for 1-dimensional signals, it also applies to 2-dimensional signals. For images you have to perform 2D-FFT/iFFT transforms.

这篇关于优化浮动模糊变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆