Main Content

Register an Image Using Normalized Cross-Correlation

This example shows how to determine the translation needed to align two images by using normalized cross-correlation.

Read Images

Read and display two images. For this example, the images are different sizes.

onion = imread("onion.png");
imshow(onion)

Figure contains an axes object. The hidden axes object contains an object of type image.

peppers = imread("peppers.png");
imshow(peppers)

Figure contains an axes object. The hidden axes object contains an object of type image.

Choose Subregions of Each Image

Choose subregions of each image so that the peak of the cross-correlation matrix will be easy to identify. It is important to choose regions that are similar. The image sub_onion will be the template, and must be smaller than the image sub_peppers. You can get these subregions by using these commands.

rect_onion = [111 33 65 58];
rect_peppers = [163 47 143 151];
sub_onion = imcrop(onion,rect_onion);
sub_peppers = imcrop(peppers,rect_peppers);

If you want to select subregions interactively, then you can use these commands.

[sub_onion,rect_onion] = imcrop(onion); % Choose the pepper below the onion
[sub_peppers,rect_peppers] = imcrop(peppers); % Choose the whole onion

Display the subregions.

imshow(sub_onion)

Figure contains an axes object. The hidden axes object contains an object of type image.

imshow(sub_peppers)

Figure contains an axes object. The hidden axes object contains an object of type image.

Calculate Normalized Cross-Correlation and Find Coordinates of Peak

Calculate the normalized cross-correlation and display it as a surface plot. The peak of the cross-correlation matrix occurs where the subimages are best correlated. normxcorr2 only works on grayscale images, so pass it the first channel of each subimage.

c = normxcorr2(sub_onion(:,:,1),sub_peppers(:,:,1));
surf(c) 
shading flat

Figure contains an axes object. The axes object contains an object of type surface.

Find the coordinates of the peak.

[max_c,imax] = max(abs(c(:)));
[ypeak,xpeak] = ind2sub(size(c),imax(1));

Find the Total Offset Between the Images

The total offset or translation between images depends on the location of the peak in the cross-correlation matrix, and on the size and position of the subimages.

% Offset found by correlation
corr_offset = [(xpeak-size(sub_onion,2)) 
               (ypeak-size(sub_onion,1))];

% Relative offset of position of subimages
rect_offset = [(rect_peppers(1)-rect_onion(1)) 
               (rect_peppers(2)-rect_onion(2))];

% Total offset
offset = corr_offset + rect_offset;
xoffset = offset(1);
yoffset = offset(2);

Register Images and Verify Results

Figure out where onion falls inside of peppers.

xbegin = round(xoffset + 1);
xend   = round(xoffset + size(onion,2));
ybegin = round(yoffset + 1);
yend   = round(yoffset + size(onion,1));

% Extract region from peppers and compare to onion
extracted_onion = peppers(ybegin:yend,xbegin:xend,:);
if isequal(onion,extracted_onion) 
   disp("onion.png was extracted from peppers.png")
end
onion.png was extracted from peppers.png

Pad the onion image to overlay on peppers, using the offset determined above.

recovered_onion = uint8(zeros(size(peppers)));
recovered_onion(ybegin:yend,xbegin:xend,:) = onion;
imshow(recovered_onion)

Figure contains an axes object. The hidden axes object contains an object of type image.

Confirm the registration by displaying one plane of the peppers image with the recovered_onion image using alpha blending.

imshowpair(peppers(:,:,1),recovered_onion,"blend")

Figure contains an axes object. The hidden axes object contains an object of type image.

See Also

|