Simo Os
Simo Os

Reputation: 153

using Mean Square Error to create an index matrix matlab

The Mean Square Error(MSE), is a method used to define the difference in between two blocks, and can be calculated as follow: a and b two blocks equal size

MSE = sqrt(sum(sum((a-b).^2)))/size(a or b)

If the MSE is less than a given threshold, than the two blocks are not diffrent.

Given two matrix A and B, the purpose is to divide the two matrix to blocks of a given size, then extract the first block from A and let it be a, then search for a block b from B where the Mean Square Error between a and b is less then a given threshold, then return the position of the block b from the matrix B. and so on. and here is an example:

Given two matrix A and B where:

A= [1 1   4 4   2 2 
    1 1   4 4   2 2

    2 2   9 9   5 5
    2 2   9 9   5 5

    3 3   4 4   9 9
    3 3   4 4   9 9];

B = [ 2 2   4 4   9 9
      2 2   4 4   9 9];

the threshold is 2

The first block a obtained from the matrix A is:

1 1
1 1

The block b obtained from the matrix B that MSR between a and b is less than the threshold is:

2 2
2 2

Therefore we return the position of the block b in the matrix B which is 1

The second block a obtained from the matrix A is:

4 4
4 4

The block b obtained from the matrix B where MSR between a and b is less than threshold is:

4 4
4 4

Therefore we return the position of the block b in the matrix B which is 2. and so on.

The final result should be as follow

RES= [1 2 1
      1 3 2
      1 2 3];

Is there a faster way?

Upvotes: 3

Views: 100

Answers (1)

Luis Mendo
Luis Mendo

Reputation: 112749

Here's a vectorized approach with bsxfun.

First define data:

A = [1 1   4 4   2 2 
     1 1   4 4   2 2
     2 2   9 9   5 5
     2 2   9 9   5 5
     3 3   4 4   9 9
     3 3   4 4   9 9];  %// data: A
B = [2 2   4 4   9 9
     2 2   4 4   9 9];  %// data: B
m = 2;                  %// number of rows per block
n = 2;                  %// number of cols per block

Then apply the following steps:

  1. Reshape matrices so that each block is a row (inspired by this great answer).
  2. Compute the MSE for all pairs of blocks.
  3. Find the argmin of the MSE with respect to blocks of B (for each block of A). Note that if there are several minimizing blocks in B this finds the first.
  4. Reshape result into a matrix.

Code:

A2 = reshape(permute(reshape(A, size(A, 1), n, []), [2 1 3]), n*m, []);  %// step 1
B2 = reshape(permute(reshape(B, size(B, 1), n, []), [2 1 3]), n*m, []);
mse = squeeze(sum(bsxfun(@minus, A2, permute(B2,[1 3 2])).^2, 1));       %// step 2
[~, result] = min(mse, [], 2);                                           %// step 3
result = reshape(result, size(A,1)/m, size(A,2)/n);                      %// step 4

Upvotes: 1

Related Questions