20

最近傍点補間アルゴリズムを使用して入力画像を拡大するための独自の関数を作成しようとしています。悪い部分は、どのように動作するのか見ることができますが、アルゴリズムそのものを見つけることができません。私はどんな助けにも感謝します。ここでMATLABの最近傍補間アルゴリズム

は、私が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 

は、あなただけの計算のためのより多くの一般式を必要とするMarkさんの提案alt text

+0

申し訳ありませんが、私が考えていたかわからないが - あなたは、出力を反復処理する必要はありません出力はより大きいので、入力。そしてその場合、私の公式は逆にする必要があります。 –

答えて

19

Aを拡張したい場合画像の最も近い近傍の補間。ここでは、それはあなたの問題に適用される方法は次のとおりです。

%# 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機能を使用することです。 EDIT

:誰もが興味を持っているEXPLANATION

ケースでは、私が

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

まず、新しい行と列のサイズを取得するには...解決策は、上記のどのように動作するか私が説明しようと思いました古い行と列のサイズには倍率が乗算されます。この結果は、floorの最も近い整数に切り捨てられます。スケールファクタが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未満のものを置き換えるためにmaxへの呼び出しがある理由である0でサイズの値のいずれかの奇妙な場合、で終わる可能性次に、行と列の両方について新しいインデックスセットが計算されます。最初に、アップサンプリングされた画像のためのインデックスのセットが計算される:1:newSize(...)。各画像ピクセルは、ピクセル1が0から1に及ぶように、ピクセル2が1から2に及ぶように、所与の幅を有するものとみなされる。したがって、ピクセルの「座標」は中心として扱われ、なぜ0.5指数から差し引かれる。これらの座標は、元の画像のピクセル中心座標のセットを与えるために倍率で除算され、元の画像の整数インデックスのセットを得るために丸められます。 minを呼び出すと、これらのインデックスのいずれも元の画像サイズoldSize(...)より大きくならないことが保証されます。

outputImage = inputImage(rowIndex,colIndex,:); 

最後に、新しいアップサンプリングされた画像は、元の画像にインデックスを付けるだけで作成されます。

+0

はすばらしい、ありがとう! – Hellnar

+0

@Hellnar:喜んで助けてください!また、コードを更新して、非整数のスケールファクタやグレースケールやRGB画像でも機能するようにしました。 – gnovice

0

後に出力されますxlocおよびyloc。

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

これは、変数に乗算結果の範囲が十分あることを前提としています。

2

MATLABは既にそれを行っています。 imresizeを使用します。

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

または私はのための簡易版を作成するためにMATLAB Image Processing Toolboximresize機能のコードを経て、バックしながら、あなたは、両方のx & yの平等、

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

私はすでにビルドイン機能を認識していますが、私は自分のコードでこれを達成する必要があります。 ありがとう – Hellnar

+1

申し訳ありませんが、わかりません!あなたがあなたの答えを見つけたのを見て嬉しいです。 – Jacob

20

この回答は、簡潔かつ効率的であることを確認するよりも説明的です。私はその点で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)のために、我々は、入力画像座標における「最も近い」場所にマップしたいということです。これは単純なマッピングがあるので、私たちは与えられたxyに(与えられた他のすべてのparams)をマップする式を使用します。私たちのケースで

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) 
+0

gnoviceのソリューションは約10倍高速です。しかし、説明に感謝します! – Wok

+0

画像IがIzoomの最近傍を使用してスケーリングされ、Izoomが同じ要素によって縮小されると、元の画像Iが返されます。直観的に、私は、ピクセルの複製のみを行い平均化を行わないので、これは非常に自然なことですが、私はより厳密な証明を見つけることはできません。私はここで誰かが私にこれに関するいくつかの指摘を与えることを望んでいた。 – idexi

関連する問題