1

I have an image:

enter image description here

I want to divide this image into 3 equal parts and calculate the SIFT for each part individually and then concatenate the results.

I found out that Matlab's blockproc does just that, but I do not know how to get it to work with my function. Here is what I have:

[r c] = size(image);
            c_new = floor(c/3); %round it 

            B = blockproc(image, [r c_new], @block_fun)

So according to Matlabs documentation the function, block_fun will be applied to the original image in blocks of size r and c_new.

this is what I wrote as block_fun

function feats = block_fun(img)
[keypoints, descriptors] = vl_sift(single(img));
feats = descriptors;
end

So, my matrix B should be a concatenation of the SIFT descriptors of all three parts of the same image? right?

But the error that I get when I run the command:

B = blockproc(image, [r c_new], @block_fun)

Function BLOCKPROC encountered an error while evaluating the user supplied function handle, FUN.

The cause of the error was:

Error using single Conversion to single from struct is not possible.

StuckInPhDNoMore
  • 2,507
  • 4
  • 41
  • 73

2 Answers2

1

This error is caused by the fact that the function that is called via its handle by blockproc expects a block struct.

The real problem is that blockproc will attempt to concatenate all results and you will have a different set of 128xN feature vectors for each block, which blockproc doesn't allow.

I think that using im2col and reshape would be much more simple.

Maurits
  • 2,082
  • 3
  • 28
  • 32
  • Thank you, yes I do get a dimensionality mismatch. Won't using `im2col`` and ``reshape`` change the structure of my descriptors and ruining the SIFT features? – StuckInPhDNoMore Mar 12 '15 at 15:38
1

For your custom function, blockproc sends in a structure where the image data is stored in a field called data. As such, you simply need to change your function so that it accesses the data field in the input. Like so:

function feats = block_fun(block_struct) %// Change
[keypoints, descriptors] = vl_sift(single(block_struct.data)); %// Change
feats = descriptors;
end
rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • This will give a subscripted assignment dimension mismatch I just realised. – Maurits Mar 10 '15 at 22:22
  • @Maurits - Yes it certainly will. I just realized what the output was. I'll wait for the OP to respond before I correct myself. – rayryeng Mar 10 '15 at 22:25
  • Thank you, the correction did make the function run but I now get a dimensionality mismatch. But even if I force it to stay within a 128 size vector by using ``rootSIFT`` instead of 3 columns of size 128 I get a fourth column of all zeros. I think ``c_new = floor(c/3); %round it `` is causing it and the rounded off area is acting as a block as well. Any way around this? – StuckInPhDNoMore Mar 12 '15 at 15:40
  • 1
    @FarazKhan - No sorry. `blockproc` processes distinct blocks. If you are trying to decompose an image into blocks which is not evenly divisible by the total number of blocks you want, you will get padding of zeroes. I don't have any suggestions for you to get this to work on your end. – rayryeng Mar 12 '15 at 17:12
  • 1
    @FarazKhan - Correcting myself because you can and I was wrong. Including a link to your latest post as a correction to myself: http://stackoverflow.com/questions/29040688/overlapping-sliding-window-over-an-image-using-blockproc-or-im2col - We can use `blockproc` to process sliding window neighbourhoods. You just have to specify the right input parameters. – rayryeng Mar 16 '15 at 15:32