MATLAB

20

में निकटतम पड़ोसी इंटरपोलेशन एल्गोरिदम मैं निकटतम पड़ोसी इंटरपोलेशन एल्गोरिदम का उपयोग कर इनपुट छवि को स्केल करने के लिए अपना स्वयं का फ़ंक्शन लिखने की कोशिश कर रहा हूं। बुरा हिस्सा यह है कि मैं यह देखने में सक्षम हूं कि यह कैसे काम करता है लेकिन एल्गोरिदम स्वयं नहीं ढूंढ सकता है। मैं किसी भी मदद के लिए आभारी रहूंगा।MATLAB

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

कुछ समय पहले मैं imresize समारोह के कोड के माध्यम से MATLAB Image Processing Toolbox में के लिए एक सरलीकृत संस्करण बनाने के लिए चला गया छवियों के निकटतम पड़ोसी इंटरपोलेशन। यह इस प्रकार से आपकी समस्या के लिए लागू किया जाएगा:

%# 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.

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 से कम कुछ भी बदलने के लिए कर सकता है इसके बाद, पंक्तियों और स्तंभों दोनों के लिए सूचकांक का एक नया सेट गणना की जाती है। सबसे पहले, अपरिपक्व छवि के लिए सूचकांक का एक समूह गणना की जाती है: 1:newSize(...)। प्रत्येक छवि पिक्सेल को दी गई चौड़ाई के रूप में माना जाता है, जैसे कि पिक्सेल 1 0 से 1 तक फैलता है, पिक्सेल 2 स्पैन 1 से 2 तक होता है .. पिक्सेल का "समन्वय" इस प्रकार केंद्र के रूप में माना जाता है, यही कारण है कि 0.5 सूचकांक से घटाया जाता है। इन निर्देशांकों को तब मूल छवि के लिए पिक्सेल-केंद्र निर्देशांक का एक सेट देने के लिए स्केल फैक्टर द्वारा विभाजित किया जाता है, जिसके बाद उनमें 0.5 जोड़ा जाता है और मूल छवि के लिए पूर्णांक सूचकांक का एक सेट प्राप्त करने के लिए गोल किया जाता है। min पर कॉल सुनिश्चित करता है कि इनमें से कोई भी सूचक मूल छवि आकार oldSize(...) से बड़ा नहीं है।

outputImage = inputImage(rowIndex,colIndex,:); 

अंत में, नई upsampled छवि बस मूल छवि में अनुक्रमणित करके बनाई गई है।

+0

महान काम करता है, धन्यवाद! – Hellnar

+0

@ हेल्लनर: मदद करने में खुशी हुई! मैंने कोड को अभी भी अपडेट किया है, इसलिए इसे गैर-पूर्णांक स्केल कारकों के साथ-साथ ग्रेस्केल या आरजीबी छवियों के लिए भी काम करना चाहिए। – gnovice

0

तुम बस गणना के लिए एक अधिक सामान्य सूत्र की आवश्यकता है:

यहाँ है कि मैं क्या 2 का एक पहलू से इनपुट छवि स्केलिंग के लिए करने की कोशिश की है xloc और yloc।

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

यह मानता है कि आपके चर के गुण गुणात्मक परिणामों के लिए पर्याप्त सीमा है।

2

MATLAB पहले से ही आपके लिए यह कर चुका है। imresize का उपयोग करें:

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

या यदि आप समान रूप से दोनों एक्स & 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 को (दिए गए अन्य सभी पैरामीटर) नक्शे का उपयोग करें:

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 अब, समझ में आता है, क्योंकि मैं समझता हूं कि चूंकि हम केवल पिक्सेल प्रतिकृति कर रहे हैं और कोई औसत नहीं है, यह काफी स्वाभाविक है, लेकिन मुझे लगता है कि एक और अधिक कठोर प्रमाण नहीं मिल रहा है। मैं उम्मीद कर रहा था कि यहां कोई मुझे इस बारे में कुछ पॉइंटर्स दे सकता है। – idexi