Алгоритм интерполяции ближайшего соседа в MATLAB

Был статья о лямбде окончательное описание, как Вам нужен осведомленный о GC диспетчер виртуальной памяти, чтобы иметь действительно эффективный GC, и отображение VM сделано главным образом аппаратными средствами в эти дни. Вот, пожалуйста :)

20
задан Community 23 May 2017 в 12:32
поделиться

4 ответа

A while back I went through the code of the imresize function in the MATLAB Image Processing Toolbox to create a simplified version for just nearest neighbor interpolation of images. Here's how it would be applied to your problem:

%# 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,:);

Another option would be to use the built-in interp2 function, although you mentioned not wanting to use built-in functions in one of your comments.

EDIT: EXPLANATION

In case anyone is interested, I thought I'd explain how the solution above works...

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

First, to get the new row and column sizes the old row and column sizes are multiplied by the scale factor. This result is rounded down to the nearest integer with floor. If the scale factor is less than 1 you could end up with a weird case of one of the size values being 0, which is why the call to max is there to replace anything less than 1 with 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));

Next, a new set of indices is computed for both the rows and columns. First, a set of indices for the upsampled image is computed: 1:newSize(...). Each image pixel is considered as having a given width, such that pixel 1 spans from 0 to 1, pixel 2 spans from 1 to 2, etc.. The "coordinate" of the pixel is thus treated as the center, which is why 0.5 is subtracted from the indices. These coordinates are then divided by the scale factor to give a set of pixel-center coordinates for the original image, which then have 0.5 added to them and are rounded off to get a set of integer indices for the original image. The call to min ensures that none of these indices are larger than the original image size oldSize(...).

outputImage = inputImage(rowIndex,colIndex,:);

Finally, the new upsampled image is created by simply indexing into the original image.

19
ответ дан 29 November 2019 в 23:48
поделиться

Этот ответ более пояснительный, чем попытка быть кратким и эффективным. Я думаю, что решение 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)
20
ответ дан 29 November 2019 в 23:48
поделиться

MATLAB уже сделал это за вас. Используйте imresize :

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

или, если вы хотите масштабировать как x, так и y одинаково,

output = imresize(input,2,'nearest');
2
ответ дан 29 November 2019 в 23:48
поделиться

Вам просто нужна более обобщенная формула для вычисления xloc и yloc.

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

Это предполагает, что ваши переменные имеют достаточный диапазон для результатов умножения.

0
ответ дан 29 November 2019 в 23:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: