Normalised Cross Correlation with Rotational Template

5 views (last 30 days)
Hello there,
I am currently trying to perform a normalised cross correlation on an image with a template (i.e. using the normxcorr2 function). The template is to be rotated through a set of angles and the correlation coefficients generated at each rotation are to be stored in a 3D array. The test image and template are shown below,
Test Image
Test Template
Below is the code which I have implemented. I hope that the comments make what I'm trying to achieve a little more clearer,
%%Correlation Test
image_file = 'Test13.bmp';
template_file = 'Test15.bmp';
image = imread(image_file); % set the image that is to be used
template = imread(template_file); % set the template that is to be used
max_template = imrotate(template, -45, 'nearest', 'loose'); % find the maximum template size at 45 degrees
dim_max = [size(max_template, 1) size(max_template, 2)]; % store the dimensions of the maximum template size
dim_image = [size(image, 1) size(image, 2)]; % store the dimensions of the image size
correlation_matrix = zeros((dim_image(1) + dim_max(1) - 1), (dim_image(2) + dim_max(2) - 1), 9); % set up the correlation matrix size (zeroed)
i = 1; % set i to 1
for angle = 0:-20:-180,
rotate_template = imrotate(template, angle, 'nearest', 'loose'); % rotate template around specified angle -- without cropping
dim_rot = [size(rotate_template, 1) size(rotate_template, 2)]; % store the dimensions of the rotated template
rotate_template_new = padarray(rotate_template, [((dim_max(1) - dim_rot(1))/2) ((dim_max(2) - dim_rot(2))/2)], 0, 'both'); % pad 'rotate_template' array with zeros
correlation_matrix(:, :, i) = normxcorr2(rotate_template_new(:,:,1), image(:,:,1)); % perform normalised cross colleration and store coefficient results in 'correlation_matrix'
i = i+1; % increment 'i' each loop
end
The problem I am having is when the program reaches this point:
"[((dim_max(1) - dim_rot(1))/2) ((dim_max(2) - dim_rot(2))/2)]"
and the difference of dim_max() and dim_rot() comes out to be an odd number. An odd number divided by 2 is not an integer - which the function padarray needs. I would like the program to be able to handle whatever the image/template dimensions - be it odd or even.
So, I'm in need of your help. What would you guys do, is there an easier way to go about this process? I only started using Matlab last week so I'm probably overthinking this process. Any help would be appreciated, and if you need any more information please say.
  1 Comment
Sam
Sam on 11 Jul 2012
I seem to have it working now,
%%Correlation Test
image_file = 'Test3.bmp';
template_file = 'Test4.bmp';
image = (imread(image_file)); % set the image that is to be used
template = (imread(template_file)); % set the template that is to be used
%max_template = imrotate(template, -45, 'nearest', 'loose'); % find the maximum template size at 45 degrees
dim_image = [size(image, 1) size(image, 2)]; % store the dimensions of the image size
i = 1; % set i to 1
% find the maximum template size by cycling through each angle
for angle = 0:-20:-180,
rotate_template = imrotate(template, angle, 'nearest', 'loose'); % rotate template around specified angle -- without cropping
dim_rot(:, :, i) = ([size(rotate_template, 1) size(rotate_template,2)]); % store the dimensions of each rotation in array 'dim_rot'
i = i + 1; % increment 'i' each loop
end
dim_max = max(dim_rot,[],3); % find the values of the rotated template with maximum dimensions
correlation_matrix = zeros((dim_image(1) + dim_max(1) - 1), (dim_image(2) + dim_max(2) - 1), i-1); % set up the correlation matrix size (zeroed)
i = 1; % reset i to 1
for angle = 0:-20:-180,
rotate_template = imrotate(template, angle, 'nearest', 'loose'); % rotate template around specified angle -- without cropping
for k = 1:2,
state = mod(size(rotate_template, k), 2);
if state == 0,
if k == 1,
rotate_template(size(rotate_template, k), :) = [];
end
if k == 2,
rotate_template(:, size(rotate_template, k)) = [];
end
end
end
dim_rot_new = [size(rotate_template, 1) size(rotate_template, 2)];
rotate_template_new = padarray(rotate_template, [((dim_max(1) - dim_rot_new(:, 1))/2) ((dim_max(2) - dim_rot_new(:, 2))/2)], 0, 'both'); % pad 'rotate_template' array with zeros
correlation_matrix(:, :, i) = normxcorr2(rotate_template_new, image); % perform normalised cross colleration and store coefficient results in 'correlation_matrix'
figure(i);
subplot(1,2,1);
imshow(rotate_template);
title('Rotated Template');
subplot(1,2,2);
imshow(correlation_matrix(:,:,i));
title('Correlated Matrix');
i = i+1; % increment 'i' each loop
end
In the end I just deleted a column or row if the rotated template proved to be even. This would make the number of rows in the rotated template odd, and since the dimensions of the maximum template were always odd, this would allows for an even difference between:
"[((dim_max(1) - dim_rot(1))/2) ((dim_max(2) - dim_rot(2))/2)]"
in the padarray.

Sign in to comment.

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!