파노라마 만들기
이 예제에서는 여러 영상을 자동으로 이어 붙여서 파노라마로 만드는 방법을 보여줍니다. 영상을 이어 붙이는 절차는 특징 기반 영상 정합의 확장입니다. 단일 영상 쌍을 정합하는 대신 여러 영상 쌍이 서로를 기준으로 연속적으로 정합되어 파노라마를 형성합니다.
영상 불러오기
이 예제에서 사용된 영상 세트에는 건물 사진이 포함되어 있습니다. 이 영상 세트는 가로 방향을 따라 왼쪽에서 오른쪽으로 무보정 스마트폰 카메라를 스윕하여 건물의 모든 부분을 캡처한 것입니다. 이 영상은 상대적으로 렌즈 왜곡의 영향을 받지 않으므로 카메라 보정이 필요하지 않습니다. 그러나 렌즈 왜곡이 있는 경우 파노라마를 만들기 전에 카메라를 보정하고 왜곡 영상을 제거해야 합니다. 필요한 경우 카메라 보정기 앱을 사용하여 카메라를 보정할 수 있습니다.
영상을 불러와서 표시합니다.
buildingDir = fullfile(toolboxdir("vision"),"visiondata","building"); buildingScene = imageDatastore(buildingDir); montage(buildingScene.Files)

여러 영상 쌍 정합하기
파노라마를 만들려면 먼저 다음 절차에 따라 연속된 여러 영상 쌍을 정합합니다.
및 간의 특징을 검출하고 매칭시킵니다.
을 에 매핑하는 기하 변환 을 추정합니다.
을 파노라마 영상에 으로 매핑하는 변환을 계산합니다.
영상 세트에서 첫 번째 영상을 읽어 들입니다.
I = readimage(buildingScene,1);
첫 번째 영상의 특징을 초기화합니다.
grayImage = im2gray(I); points = detectSURFFeatures(grayImage); [features,points] = extractFeatures(grayImage,points);
모든 변환을 단위 행렬로 초기화합니다. 건물 영상이 카메라에 상당히 가깝기 때문에 사영 변환이 사용됩니다. 더 먼 거리에서 캡처된 장면에는 아핀 변환을 사용해 보십시오.
numImages = numel(buildingScene.Files); tforms(numImages) = projtform2d;
영상 크기를 유지하기 위해 변수를 초기화합니다.
imageSize = zeros(numImages,2);
나머지 영상 쌍에 대해 반복합니다. 각 영상에 대해 이전 영상의 점과 특징을 저장합니다. 읽어 들인 다음 회색조로 변환하고 영상 크기를 저장합니다. 영상에서 SURF 특징을 검출하고 추출하여 해당 영상과 이전 영상 간의 대응점을 찾습니다. 그런 다음 두 대응점 간의 변환을 추정합니다.
for n = 2:numImages pointsPrevious = points; featuresPrevious = features; I = readimage(buildingScene, n); grayImage = im2gray(I); imageSize(n,:) = size(grayImage); points = detectSURFFeatures(grayImage); [features,points] = extractFeatures(grayImage,points); indexPairs = matchFeatures(features,featuresPrevious,Unique=true); matchedPoints = points(indexPairs(:,1), :); matchedPointsPrev = pointsPrevious(indexPairs(:,2), :); tforms(n) = estgeotform2d(matchedPoints, matchedPointsPrev,... "projective",Confidence=99.9,MaxNumTrials=2000); tforms(n).A = tforms(n-1).A * tforms(n).A; end
이 단계에서 tforms의 모든 변환은 첫 번째 영상을 기준으로 하며, 이는 영상을 순차적으로 처리할 수 있게 하여 영상 정합 절차의 코딩을 단순화하는 방법입니다. 그러나 첫 번째 영상으로 파노라마를 시작하면 파노라마를 구성하는 대부분의 영상이 왜곡될 수 있기 때문에 보기 좋지 않은 결과가 생성되는 경우가 많습니다. 장면의 중심이 가장 덜 왜곡되도록 변환을 조정하면 시각적으로 더 멋진 파노라마를 얻을 수 있습니다. 이러한 개선을 위해서는 장면의 중심이 되는 영상에 대한 변환을 반전하고 이 반전된 변환을 모든 다른 영상에 적용하면 됩니다. 먼저, projtform2d outputLimits 메서드를 사용하여 각 변환에 대한 출력 제한을 구합니다. 그런 다음 출력 제한을 사용하여 대략적으로 장면의 중심이 되는 영상을 자동으로 찾습니다.
각 변환에 대한 출력 제한을 계산합니다.
for idx = 1:numel(tforms) [xlim(idx,:),ylim(idx,:)] = outputLimits(tforms(idx),[1 imageSize(idx,2)],[1 imageSize(idx,1)]); end
다음으로 각 변환에 대한 평균 X 제한값을 계산하고 장면의 중심이 되는 영상을 찾습니다. 이 장면은 가로 방향이기 때문에 여기서는 X 제한값만 사용됩니다. 다른 영상 세트를 사용하는 경우 장면의 중심이 되는 영상을 찾으려면 X 제한값과 Y 제한값 모두를 사용해야 할 수 있습니다.
avgXLim = mean(xlim, 2); [~,idx] = sort(avgXLim); centerIdx = floor((numel(tforms)+1)/2); centerImageIdx = idx(centerIdx);
마지막으로 장면의 중심이 되는 영상의 역변환을 모든 다른 영상에 적용합니다.
Tinv = invert(tforms(centerImageIdx)); for idx = 1:numel(tforms) tforms(idx).A = Tinv.A * tforms(idx).A; end
파노라마 초기화하기
모든 영상이 매핑되는 초기의 빈 파노라마를 만듭니다. outputLimits 메서드를 사용하여 모든 변환에 대한 최소 출력 제한과 최대 출력 제한을 계산합니다. 이 값은 파노라마 크기를 자동으로 계산하는 데 사용됩니다.
for idx = 1:numel(tforms) [xlim(idx,:),ylim(idx,:)] = outputLimits(tforms(idx),[1 imageSize(idx,2)],[1 imageSize(idx,1)]); end maxImageSize = max(imageSize);
최소 출력 제한과 최대 출력 제한을 구합니다.
xMin = min([1; xlim(:)]); xMax = max([maxImageSize(2); xlim(:)]); yMin = min([1; ylim(:)]); yMax = max([maxImageSize(1); ylim(:)]);
파노라마의 너비와 높이를 계산합니다.
width = round(xMax - xMin); height = round(yMax - yMin);
영상 I의 유형 및 특성과 일치하는, 차원이 [height width 3]인 0으로 구성된 배열을 설정하여 빈 캔버스로 파노라마를 초기화합니다.
panorama = zeros([height width 3],"like",I);파노라마 만들기
imwarp 함수를 사용하여 영상을 파노라마에 매핑하고 imblend 함수를 사용하여 영상을 함께 오버레이합니다.
2차원 공간 참조 객체를 만들어 파노라마의 크기를 정의합니다.
xLimits = [xMin xMax]; yLimits = [yMin yMax]; panoramaView = imref2d([height width],xLimits,yLimits);
각 영상에 워핑을 적용하여 파노라마로 변환하여 파노라마를 만듭니다. 그런 다음 이진 마스크를 생성하고 워핑이 적용된 영상을 파노라마에 중첩합니다.
for idx = 1:numImages I = readimage(buildingScene,idx); warpedImage = imwarp(I,tforms(idx),OutputView=panoramaView); mask = imwarp(true(size(I,1),size(I,2)),tforms(idx),OutputView=panoramaView); panorama = imblend(warpedImage,panorama,mask,foregroundopacity=1); end imshow(panorama)

참고 문헌
[1] Matthew Brown and David G. Lowe. 2007. Automatic Panoramic Image Stitching using Invariant Features. Int. J. Comput. ion 74, 1 (August 2007), 59-73.