문제

가장 가까운 이웃 보간 알고리즘을 사용하여 입력 이미지를 확장하기위한 내 기능을 작성하려고합니다. 나쁜 부분은 그것이 어떻게 작동하는지 볼 수 있지만 알고리즘 자체를 찾을 수 없다는 것입니다. 도움을 주셔서 감사합니다.

입력 이미지를 2의 계수로 확장하려는 시도는 다음과 같습니다.

function output = nearest(input)
[x,y]=size(input);
output = repmat(uint8(0),x*2,y*2);
[newwidth,newheight]=size(output);
for i=1:y
    for j=1:x
        xloc = round ((j * (newwidth+1)) / (x+1));
        yloc = round ((i * (newheight+1)) / (y+1));
        output(xloc,yloc) = input(j,i);
    end
end

다음은 출력이 있습니다 표시제안 alt text

도움이 되었습니까?

해결책

얼마 전 나는 imresize 기능 MATLAB 이미지 처리 도구 상자 가장 가까운 이웃 이미지 보간을위한 단순화 된 버전을 만듭니다. 문제에 어떻게 적용되는지는 다음과 같습니다.

%# Initializations:

scale = [2 2];              %# The resolution scale factors: [rows columns]
oldSize = size(inputImage);                   %# Get the size of your image
newSize = max(floor(scale.*oldSize(1:2)),1);  %# Compute the new image size

%# Compute an upsampled set of indices:

rowIndex = min(round(((1:newSize(1))-0.5)./scale(1)+0.5),oldSize(1));
colIndex = min(round(((1:newSize(2))-0.5)./scale(2)+0.5),oldSize(2));

%# Index old image to get new image:

outputImage = inputImage(rowIndex,colIndex,:);

또 다른 옵션은 내장을 사용하는 것입니다 interp2 기능, 귀하의 의견 중 하나에서 내장 기능을 사용하고 싶지 않다고 언급했지만.

편집 : 설명

누구나 관심이 있으시면 위의 솔루션이 어떻게 작동하는지 설명 할 것이라고 생각했습니다.

newSize = max(floor(scale.*oldSize(1:2)),1);

먼저 새 행과 열 크기를 얻으려면 이전 행과 열 크기에 스케일 계수가 곱합니다. 이 결과는 가장 가까운 정수로 반올림됩니다. floor. 스케일 팩터가 1 미만인 경우 크기 값 중 하나가 0 인 이상한 경우가 될 수 있으므로 호출이 발생할 수 있습니다. max 1보다 작은 것을 1로 교체 할 수 있습니다.

rowIndex = min(round(((1:newSize(1))-0.5)./scale(1)+0.5),oldSize(1));
colIndex = min(round(((1:newSize(2))-0.5)./scale(2)+0.5),oldSize(2));

다음으로 행과 열 모두에 대해 새로운 지수 세트가 계산됩니다. 먼저, 샘플링 된 이미지에 대한 인덱스 세트가 계산됩니다. 1:newSize(...). 각 이미지 픽셀은 주어진 너비를 갖는 것으로 간주되며, 픽셀 1은 0에서 1까지, 픽셀 2는 1에서 2까지의 픽셀 2 스파입니다. 픽셀의 "좌표"는 중심으로 처리되므로 0.5 지수에서 빼냅니다. 그런 다음이 좌표를 스케일 팩터로 나누어 원래 이미지에 대한 픽셀 중심 좌표 세트를 제공 한 다음 0.5를 추가하고 원래 이미지에 대한 정수 지수 세트를 얻기 위해 반올림됩니다. 전화 min 이 지수 중 어느 것도 원래 이미지 크기보다 크지 않도록합니다. oldSize(...).

outputImage = inputImage(rowIndex,colIndex,:);

마지막으로, 새로운 업 샘플링 된 이미지는 원래 이미지로 간단히 인덱싱하여 생성됩니다.

다른 팁

이 답변은 간결하고 효율적이 되려고 노력하는 것보다 더 설명 적입니다. 제 생각에는 gnovice솔루션은 그와 관련하여 가장 좋습니다. 그것이 어떻게 작동하는지 이해하려는 경우 계속 읽으십시오 ...

이제 코드의 문제는 입력 이미지에서 출력 이미지로 위치를 매핑하고 있다는 것입니다. 반점 산출. 입력 이미지가 모두 흰색이고 출력이 검은 색으로 초기화 된 예를 고려하면 다음을 얻습니다.

screenshot

당신이해야 할 일은 (출력에서 입력까지) 반대입니다. 설명하기 위해 다음 표기법을 고려하십시오.

1           c         1                 scaleC*c
+-----------+ 1       +----------------------+ 1
|    |      |         |        |             |
|----o      |   <===  |        |             |
|  (ii,jj)  |         |--------o             |
+-----------+ r       |      (i,j)           |
  inputImage          |                      |
                      |                      |
                      +----------------------+ scaleR*r
                            ouputImage

Note: I am using matrix notation (row/col), so:
  i ranges on [1,scaleR*r] , and j on [1,scaleC*c]
  and ii on [1,r], jj on [1,c]

아이디어는 각 위치에 대한 것입니다 (i,j) 출력 이미지에서는 입력 이미지 좌표의 "가장 가까운"위치에 매핑하려고합니다. 이것은 간단한 매핑이기 때문에 우리는 주어진 것을 맵핑하는 공식을 사용합니다. x 에게 y (다른 모든 매개 변수가 주어진) :

 x-minX      y-minY
--------- = ---------
maxX-minX   maxY-minY

우리의 경우, x 입니다 i/j 좌표와 y 입니다 ii/jj 동등 어구. 그러므로 각각을 대체하면 다음과 같이됩니다.

jj = (j-1)*(c-1)/(scaleC*c-1) + 1
ii = (i-1)*(r-1)/(scaleR*r-1) + 1

조각을 합치면 다음 코드를 얻습니다.

% read a sample image
inputI = imread('coins.png');
[r,c] = size(inputI);
scale = [2 2];        % you could scale each dimension differently

outputI = zeros(scale(1)*r,scale(2)*c, class(inputI));

for i=1:scale(1)*r
    for j=1:scale(2)*c
        % map from output image location to input image location
        ii = round( (i-1)*(r-1)/(scale(1)*r-1)+1 );
        jj = round( (j-1)*(c-1)/(scale(2)*c-1)+1 );

        % assign value
        outputI(i,j) = inputI(ii,jj);
    end
end

figure(1), imshow(inputI)
figure(2), imshow(outputI)

Matlab은 이미 당신을 위해 그것을했습니다. 사용 imresize:

output = imresize(input,size(input)*2,'nearest');

또는 X & Y를 동일하게 확장하려면

output = imresize(input,2,'nearest');

XLOC 및 YLOC를 계산하기위한보다 일반화 된 공식 만 있으면됩니다.

xloc = (j * (newwidth+1)) / (x+1);
yloc = (i * (newheight+1)) / (y+1);

이는 변수에 곱셈 결과에 충분한 범위가 있다고 가정합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top