clc
clear
% 读取和载入图片
buildingDir = fullfile(toolboxdir('vision'), 'visiondata',
'building');
buildingScene = imageDatastore(buildingDir);
montage(buildingScene.Files);
%读取第一幅图像从图像中
I = readimage(buildingScene,1);
grayImage = rgb2gray(I);
points =detectSURFFeatures(grayImage);
[features,points] = extractFeatures(grayImage,points);
numImages = numel(buildingScene.Files);
tforms(numImages) = projective2d(eye(3));
I_pre = I;
for n = 2:numImages
%store points and
features for I(n-1).
pointsPrevious =
points;
featuresPrevious =
features;
%Read I(n).
I =
readimage(buildingScene, n);
%
Detect and extract SURFfeatures for I(n)
grayImage = rgb2gray(I);
points
= detectSURFFeatures(grayImage);
[features, points] = extractFeatures(grayImage,
points);
% Find correspondences
between I(n) and I(n-1).
indexPairs =
matchFeatures(features, featuresPrevious, 'Unique', true);
matchedPoints =
points(indexPairs(:,1), :);
matchedPointsPrev =
pointsPrevious(indexPairs(:,2), :);
% Estimate the
transformation between I(n) and I(n-1).
[tforms(n),inlierBoxPoints, inlierScenePoints] =
estimateGeometricTransform(matchedPoints,
matchedPointsPrev,'projective', 'Confidence', 99.9, 'MaxNumTrials',
2000);
% %
Compute T(1) * ... * T(n-1) * T(n)
% figure,showMatchedFeatures(I,I_pre,inlierBoxPoints,inlierScenePoints,
'montage');
% I_pre = I;
tforms(n).T =
tforms(n-1).T * tforms(n).T;
end
imageSize = size(I); % all the images are
the same size
% Compute the output limits for each
transform
% Compute the output limits for each
transform
for i = 1:numel(tforms)
[xlim(i,:), ylim(i,:)] =
outputLimits(tforms(i), [1 imageSize(2)], [1 imageSize(1)]);
end
avgXLim = mean(xlim, 2);
[~, idx] = sort(avgXLim);
centerIdx = floor((numel(tforms)+1)/2);
centerImageIdx = idx(centerIdx);
Tinv = invert(tforms(centerImageIdx));
for i = 1:numel(tforms)
tforms(i).T = Tinv.T * tforms(i).T;
end
for i = 1:numel(tforms)
[xlim(i,:), ylim(i,:)] = outputLimits(tforms(i),
[1 imageSize(2)], [1 imageSize(1)]);
end
xMin = min([1;xlim(:)]);
xMax = max([imageSize(2); xlim(:)]);
yMin = min([1; ylim(:)]);
yMax = max([imageSize(1); ylim(:)]);
% %
% Width and height of panorama.
width = round(xMax - xMin);
height = round(yMax - yMin);
% Create the panorama.
I = readimage(buildingScene, 1);
T = double(tforms(1,1).T);
H = maketform('projective',T);
g = imtransform(I,H,'XData',[xMin xMax],'YData',[yMin
yMax]);
warp =
imtransform(uint8(ones(size(I,1),size(I,2),3)),H,'XData',[xMin
xMax],'YData',[yMin yMax]);
[h,w] = size(rgb2gray(g));
panorama = uint8(zeros(h,w,3));
panorama = panorama + g.*warp;
for i = 2:numImages
warpPrevious =
warp;
I =
readimage(buildingScene, i);
% Transform I into the
panorama.
T =
double(tforms(1,i).T);
H =
maketform('projective',T);
g =
imtransform(I,H,'XData',[xMin xMax],'YData',[yMin yMax]);
% Generate a binary
mask.
warp =
imtransform(uint8(ones(size(I,1),size(I,2),3)),H,'XData',[xMin
xMax],'YData',[yMin yMax]);
% Overlay the
warpedImage onto the panorama.
ghost =
(1-warpPrevious).*warp;
panorama =
panorama + g.*ghost;
end
figure,imshow(panorama)