MATLAB中的最近邻插值algorithm

我正在尝试使用最近邻居插值algorithm来编写我自己的扩大input图像的函数。 不好的部分是我能够看到它是如何工作的,但无法findalgorithm本身。 我会很感激任何帮助。

以下是我尝试将input图像放大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 

这是马克的build议后的输出 替代文字

前一阵子,我在MATLABimage processing工具箱中查看了imresize函数的代码,为图像的最近邻插值创build了一个简化版本。 以下是如何应用于您的问题:

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

另一个select是使用内置的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等。像素的“坐标”因此被视为中心,这是为什么0.5从指数中减去。 然后将这些坐标除以缩放因子,得到原始图像的一组像素中心坐标,然后对它们加0.5,并四舍五入以获得原始图像的一组整数索引。 对min的调用确保这些索引都不会大于原始图像大小oldSize(...)

 outputImage = inputImage(rowIndex,colIndex,:); 

最后,通过简单地索引到原始图像中来创build新的上采样图像。

这个答案比试图简洁和高效更具有说服力。 我认为gnovice的解决scheme在这方面是最好的。 如果你想了解它是如何工作的,请继续阅读…

现在,你的代码的问题是,你是从input图像的位置映射到输出图像,这就是为什么你得到的斑点输出。 考虑一个例子,其中input图像全白,输出初始化为黑色,我们得到以下结果:

截图

你应该做的是相反的(从输出到input)。 为了说明,请考虑以下标记:

 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) ,我们希望将其映射到input图像坐标中的“最近”位置。 由于这是一个简单的映射,我们使用公式将给定的x映射到y (给出所有其他参数):

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

在我们的例子中, xi / j坐标, yii / 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); 

这假设你的variables有足够的范围来乘法结果。