views:

170

answers:

3

Is there a filtering algorithm that converges at some shape? My problem is that I am filtering a two dimensional graph, and applying filtering repeatedly. I'm down-sampling data and re-sampling it using gaussian filters (footprints), but the graph changes its shape with every subsequent filtering. What I need is to achieve some final shape, so that after enough filtering, the graph will no longer change shape.

EDIT: by filtering I mean smoothing out, not dropping some information.

+2  A: 

The simple answer is no. Mathematically filtering with a Gaussian means that you're convolving your data with a Gaussian. But convolving is the same as multiplying in the Fourier domain, so repeated application of the filter is like repeated multiplications in the Fourier domain, and here you can see that things will either blow up or go to zero. There might be something else that's also validly called filtering that doesn't do this, and you might be able make or dig something up that will do what you want, but repeated convolutions with the same kernel, Gaussian or otherwise, will not converge.

tom10
Good to know! Thanks
AareP
While the answer is correct for linear filters, there definitely is "something else that's also validly called filtering", namely the class of non-linear filters.
Pukku
A: 

Found a pretty good hack to this problem. I'm not repeatedly re-filtering the data, but re-assigning weights-values to individual values of the 2d graph. This weight-value tells me how much filtering should be applied to corresponding graph locations. This weight-value also tells us the width of the gaussian filter (the range the value affects). Here's the code that needs to be executed every time graph values change.

vector<float> graph_values(100);
vector<float> graph_weights(100);
vector<float> graph_filtered_values(100);

// temp
vector<float> accumulated_weights(graph_values.size());


for(int x1=0;x1<graph_values.size();x1++)
{
 graph_filtered_values[x1] = 0;

 for(int x2=x1-30;x2<=x1+30;x2++)
 {
    float w = expf(-.5*(float)(x2-x1)*(x2-x1)/(graph_weights[x2]*graph_weights[x2]));

    if( x2==x1&&!_finite(w) )
     w = 1;
    if( w<0.0001 ) 
     w = 0;

    graph_filtered_values[x1] += graph_values[x2] * w;

    accumulated_weights[x1] += w;
 }
}

for(int x1=0;x1<graph_values.size();x1++)
{
 graph_filtered_values[x1] /= accumulated_weights[x1];
}

This algorithm uses triple the amount of memory: for graph_values, graph_weights and graph_filtered_values. This can be optimized by dropping first two arrays in the end product, when graph values no longer change.

AareP
A: 

You might want to try a median filter.

The median filter is a special case of nonlinear filters used for smoothing signals. Since the output of the median filter is always one of the input samples, it is conceivable that certain signals could pass through the median filter unaltered. These signals define the signature of a filter and are referred to as root signals. Median filters are known to possess the convergence property, meaning that by repeating median filtering a root signal will be found, starting from any input signal.
(Burian Adrian, Kuosmanen Pauli: Tuning the smoothness of the recursive median filter, IEEE Transactions on Signal Processing 50(7), pp. 1631-1639, 2002)

Pukku