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)
peppers = imread("peppers.png");
imshow(peppers)
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)
imshow(sub_peppers)
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
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)
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")