MATLAB - Сопоставленные функции в Panorama - PullRequest
0 голосов
/ 20 мая 2019

Я использовал предоставленный Mathsworks пример для сшивания панорамных изображений: https://uk.mathworks.com/help/vision/examples/feature-based-panoramic-image-stitching.html, и он отлично работает. Однако я пытаюсь реализовать это для большего набора изображений (20 по сравнению с примерами 5). Однако в результате появляется несколько сообщений об ошибках.

Это сообщения об ошибках:

Ошибка при использовании оценкиGeometricTransform> checkRuntimeStatus (строка 177) matchedPoints1 и matchedPoints2 не имеют достаточно точек. Количество баллов в каждом наборе должно быть не менее 4.

Ошибка в оценке GeometricTransform (строка 159) checkRuntimeStatus (statusCode, status, sampleSize);

Ошибка в Exemplar (строка 70) tforms (n) = оценкаGeometricTransform (matchedPoints, matchedPointsPrev, ...

clear;
close all;

% Load images.
buildingDir = fullfile('my image location');
%buildingDir = fullfile(toolboxdir('vision'), 'visiondata', 'building');
buildingScene = imageDatastore(buildingDir);

% Display images to be stitched
montage(buildingScene.Files);

% Read the first image from the image set.
I = readimage(buildingScene, 1);

% Initialize features for I(1)
grayImage = rgb2gray(I);
points = detectSURFFeatures(grayImage);
[features, points] = extractFeatures(grayImage, points);


% Initialize all the transforms to the identity matrix. Note that the
% projective transform is used here because the building images are fairly
% close to the camera. Had the scene been captured from a further distance,
% an affine transform would suffice.
numImages = numel(buildingScene.Files);
tforms(numImages) = projective2d(eye(3));
%tforms(numImages) = affine2d(eye(3));

% Initialize variable to hold image sizes.
imageSize = zeros(numImages,2);

% Iterate over remaining image pairs
for n = 2:numImages

    % Store points and features for I(n-1).
    pointsPrevious = points;
    featuresPrevious = features;

    % Read I(n).
    I = readimage(buildingScene, n);

    % Convert image to grayscale.
    grayImage = rgb2gray(I);
    %figure(3), imshow(grayImage);

    % Save image size.
    imageSize(n,:) = size(grayImage);

    % Detect and extract SURF features for I(n).
    points = detectSURFFeatures(grayImage);
    [features, points] = extractFeatures(grayImage, points);

    % Find correspondences between I(n) and I(n-1).
    % ORIGINAL CODE
    indexPairs = matchFeatures(features, featuresPrevious, 'Unique', true);
    matchedPoints = points(indexPairs(:,1), :);
    matchedPointsPrev = pointsPrevious(indexPairs(:,2), :);

    % ALTERED
    %indexPairs = matchFeatures(features, featuresPrevious, 'Unique', true);
    %matchedPoints = points(indexPairs(1:20, 1));
    %matchedPointsPrev = pointsPrevious(indexPairs(1:20, 2));

    %indexPairs = matchFeatures(features, featuresPrevious, 'Unique', true) ;
    %matchedPoints = points(indexPairs(1:2, 1));
    %matchedPointsPrev = pointsPrevious(indexPairs(1:2, 2));

    % Estimate the transformation between I(n) and I(n-1).
   tforms(n) = estimateGeometricTransform(matchedPoints, matchedPointsPrev,...
   'projective', 'Confidence', 99.9, 'MaxNumTrials', 4000);

    % Compute T(n) * T(n-1) * ... * T(1)
    tforms(n).T = tforms(n).T * tforms(n-1).T;
end

% Compute the output limits  for each transform
for i = 1:numel(tforms)
    [xlim(i,:), ylim(i,:)] = outputLimits(tforms(i), [1 imageSize(i,2)], [1 imageSize(i,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 = tforms(i).T * Tinv.T;
end

for i = 1:numel(tforms)
    [xlim(i,:), ylim(i,:)] = outputLimits(tforms(i), [1 imageSize(i,2)], [1 imageSize(i,1)]);
end

maxImageSize = max(imageSize);

% Find the minimum and maximum output limits
xMin = min([1; xlim(:)]);
xMax = max([maxImageSize(2); xlim(:)]);

yMin = min([1; ylim(:)]);
yMax = max([maxImageSize(1); ylim(:)]);

% Width and height of panorama.
width  = round(xMax - xMin);
height = round(yMax - yMin);

% Initialize the "empty" panorama.
panorama = zeros([height width 3], 'like', I);

blender = vision.AlphaBlender('Operation', 'Binary mask', 'MaskSource', 'Input port');

% Create a 2-D spatial reference object defining the size of the panorama.
xLimits = [xMin xMax];
yLimits = [yMin yMax];
panoramaView = imref2d([height width], xLimits, yLimits);

% Create the panorama.
for i = 1:numImages

    I = readimage(buildingScene, i);

    % Transform I into the panorama.
    warpedImage = imwarp(I, tforms(i), 'OutputView', panoramaView);

    % Generate a binary mask.
    mask = imwarp(true(size(I,1),size(I,2)), tforms(i), 'OutputView', panoramaView);

    % Overlay the warpedImage onto the panorama.
    panorama = step(blender, panorama, warpedImage, mask);
end

figure, imshow(panorama)

Я использовал приложение «Оценщик регистрации», чтобы просмотреть подходящие функции, и некоторые из них имеют очень маленькие соответствия. Я действительно изо всех сил пытаюсь узнать, что нужно изменить в коде, чтобы он работал для моего набора изображений. Это мой набор изображений: https://imgur.com/a/bZynqmF

Любой совет или помощь будут великолепны :)

...