0

I'm trying to run a customized filter through an image, using the colfilt function. This filter basically runs a window nxn through the image, and replaces the central pixel by the half of its minimum and maximum sum. This is what the code looks like:

colfilt(image, 3, "sliding", @(x) (min(x(:))+max(x(:)))/2)

However, I'm getting this error:

error: col2im: can't resize B in matrix sized (A_SIZE - BLOCK_SIZE +1)
error: called from:
error:   /usr/share/octave/packages/image-2.2.1/col2im.m at line 143, column 9
error:   /usr/share/octave/packages/image-2.2.1/colfilt.m at line 152, column 9

If I replace the function by the nfilter, like below

nlfilter(image, [n n], @(x) (min(x(:))+max(x(:)))/2)

It works fine, but it's too slow, so I think the first option must work better.

Does anyone know how to make it work?

Thanks in advance.

gcolucci
  • 438
  • 1
  • 5
  • 21
  • It looks like the size of the matrix to which you are assigning the result of `colfilt` should be the size of A - blocks_size (3 in your case) + 1 = size of A - 2 and it does not have such dimensions. – Cheery Oct 19 '14 at 04:12
  • But I'm not assigning the result to any variable – gcolucci Oct 19 '14 at 04:15
  • You - not, but col2im is called by colfilt and it does. What are the dimensions of the original image? Try to use not just `3`, but `[3 3]` – Cheery Oct 19 '14 at 04:16
  • I'm testing it at a 6x6 fake matrix. The original image is 512x512. I had the same error with `[3 3]` – gcolucci Oct 19 '14 at 04:19

1 Answers1

2

You need to read the documentation of colfilt more carefully. Here's what it says about the sliding option:

B = colfilt(A,[M N],'sliding',FUN) rearranges each M-by-N sliding
neighborhood of A into a column in a temporary matrix, and then applies
the function FUN to this matrix. FUN must return a row vector containing
a single value for each column in the temporary matrix. (Column
compression functions such as SUM return the appropriate type of
output.) colfilt then rearranges the vector returned by FUN into a
matrix of the same size as A.

The key sentence is: FUN must return a row vector containing a single value for each column in the temporary matrix. What colfilt does is that it transforms each pixel neighbourhood into a single column and concatenates all of these columns to be placed into a temporary matrix. Therefore, each column represents a single pixel neighbourhood. As such, you need to write your anonymous function such that the output will be a single row vector, where each element in this row vector is the output result of what would happen if you applied your function to each pixel neighbourhood that is located in each column of this temporary matrix. As such, you simply need to modify your anonymous function to do this instead:

out = colfilt(image, [3 3], 'sliding', @(x) ((min(x)+max(x))/2));

Note that you need to specify the second input as [3 3], and not just a single number of 3 as noticed in the comments in your post. This should now independently find the minimum for each column, add this with the maximum of each column, then divide by 2. This row vector should now output what the result would be for each pixel neighbourhood that you have processed.

rayryeng
  • 102,964
  • 22
  • 184
  • 193