MATLAB中的滑动窗口最小和最大滤波器

信息处理 过滤器 matlab
2022-02-05 19:10:37

我正在尝试将滑动窗口最小和最大过滤器应用于特定窗口大小的图像。实际上,我正在尝试为它找到最佳的窗口大小。但我真的没有掌握它的窍门。我想我应该用它blockproc来实现滑动窗口,但不确定如何找到最大和最小过滤器。至于实现本身,我应该使用循环将窗口滑过图像的整个区域吗?

2个回答

ordfilt2将为您执行此操作:

N=5;
filtered_img = ordfilt2(img, 1, true(N));

对于最小和

filtered_img = ordfilt2(img, N*N, true(N));

为最大值。您还可以使用imdilateimerode执行最大和最小过滤器。

老问题,但这是 C 中的答案(不是 MATLAB)

一种有效的滑动最大值算法,其计算成本为在下面的代码中O(log2(L))window_lengthL

算法来自:

布鲁克斯:“提高最坏情况性能的最大和最小滤波器算法”IEEE 电路和系统汇刊—II:模拟和数字信号处理,卷。47,没有。2000 年 9 月 9 日

C代码是我的。

#define A_REALLY_LARGE_NUMBER 3.40e38
 
typedef struct
   {
   unsigned long window_length;         // array_size/2 < window_length <= array_size
   unsigned long array_size;            // must be power of 2 for this simple implementation
   unsigned long input_index;           // the actual sample placement is at (array_size + input_index);
   float* big_array_base;               // the big array is malloc() separately and is actually twice array_size;
   } search_tree_array_data;


void initSearchArray(unsigned long window_length, search_tree_array_data* array_data)
   {
   array_data->window_length = window_length;
 
   array_data->array_size = 1;
   window_length--;
   while (window_length > 0)
       {
       array_data->array_size <<= 1;
       window_length >>= 1;
       }
   // array_size is a power of 2 such that
   // window_length <= array_size < 2*window_length
   // array_size = 2^ceil(log2(window_length)) = 2^(1+floor(log2(window_length-1)))
 
   array_data->input_index = 0;
 
   array_data->big_array_base = (float*)malloc(sizeof(float)*2*array_data->array_size);        // dunno what to do if malloc() fails.
 
   for (unsigned long n=0; n<2*array_data->array_size; n++)
       {
       array_data->big_array_base[n] = -A_REALLY_LARGE_NUMBER;        // init array.
       }                                                              // array_base[0] is never used.
    }



/*
 *   findMaxSample(value, &array_data) will place "value" into the circular
 *   buffer in the latter half of the array pointed to by array_data->big_array_base .
 *   it will then compare the value in "value" to its "sibling" value, takes the
 *   greater of the two and then pops up one generation to the parent node where 
 *   this parent also has a sibling and repeats the process.  since the other parent  
 *   nodes already have the max value of the two child nodes, when getting to the
 *   top-level parent node, this node will have the maximum value of all the samples
 *   in the big_array.  the number of iterations of this loop is ceil(log2(window_length)).
 */
 
float findMaxSample(float value, search_tree_array_data* array_data)
   {
   register float* big_array = array_data->big_array_base;
 
   register unsigned long index = array_data->array_size + array_data->input_index;        // our main buffer is in the latter half of the big array.
 
   while (index > 1UL)
      {
      big_array[index] = value;
 
      register float sibling_value = big_array[index ^ 1UL];        // toggle LSB, the upper bits of the sibling address are the same.
 
      if (value < sibling_value)
         {
         value = sibling_value;                        // use maximum of the two values
         }
 
      index >>= 1;                                     // parent address is index/2 (drop remainder or "sibling bit")
      }
 
   array_data->input_index++;
   if (array_data->input_index >= array_data->window_length)
      {
      array_data->input_index = 0;
      }
 
   return value;
   }