2016-03-02 147 views
0

我需要找到像素的所有黑鄰域;對於我嘗試以下,但輸出不correct.Cropped輸入圖像是 enter image description here 標記圖像(我把顏色到該標籤) enter image description here 我想添加的輸入圖像的黑色區域(區域周圍像橢圓結構)和改變周圍的橢圓形白色區域標記的圖像爲藍色(需要改變周圍的白色區域爲1)的標籤如何找到一個像素的鄰域和它的座標

clc 
    clear all;close all 
    img=[0 255 0 0 0; 
     0 1 1 255 0; 
     255 0 0 255 0;]; 
    [m n]=size(img) 
    img= padarray(img, [2 2], 0) 
    fi_neighbors=zeros(1,8); 
    for i=1:m 
     for j=1:n 
    for r=3:m 
     for c=3:n 

      neighbors(1) = img(r-1,c-1); % Upper left. 
    neighbors(2) = img(r-1,c); % Upper middle. 
    neighbors(3) = img(r-1,c+1); % Upper right. 
    neighbors(4) = img(r,c-1); % left. 
    neighbors(5) = img(r,c+1); % right. 
    neighbors(6) = img(r+1,c+1); % Lowerleft. 
    neighbors(7) = img(r+1,c); % lower middle. 
    neighbors(8) = img(r+1,c-1); % Lower left. 
     end 

    end 
    fi_neighbors=[neighbors;fi_neighbors] 
     end 
    end 
+2

這是不是正確的?又名,它目前輸出了什麼? – Adriaan

+0

預期產量是多少?該代碼只是簡單地將圖像中每個像素的所有8個像素鄰域強度連接成一個巨型陣列。 – rayryeng

+1

您在2個​​內部循環中覆蓋結果的事實可能會很麻煩。你計算一些元素,然後放在'neighbors(1:8)'中。你在循環中每次都這樣做。除此之外。有最近鄰計算的Matlab函數。最好的選擇取決於你想要做什麼。除此之外。如果代碼看起來像在Matlab的問題中爲你做的那樣,你應該考慮重新格式化。這可以通過標記所有內容並選擇重新格式化或菜單中的某些內容來完成。 – patrik

回答

2

有在你的代碼的幾個錯誤,所以我會盡量採取他們一個接一個。這裏是你的原代碼,重新格式化了一下:

img = [0 0 0 0 0; 
     0 1 1 0 0; 
     0 0 0 0 0;]; 
[m n] = size(img) 
img = padarray(img, [2 2], 0) 
fi_neighbors = zeros(1,8); 

for i = 1:m 
    for j = 1:n 
     for r = 3:m 
     for c = 3:n 
      neighbors(1) = img(r-1,c-1); % Upper left. 
      neighbors(2) = img(r-1,c); % Upper middle. 
      neighbors(3) = img(r-1,c+1); % Upper right. 
      neighbors(4) = img(r,c-1); % left. 
      neighbors(5) = img(r,c+1); % right. 
      neighbors(6) = img(r+1,c+1); % Lower right. <-- corrected 
      neighbors(7) = img(r+1,c); % lower middle. 
      neighbors(8) = img(r+1,c-1); % Lower left. 
     end 
     end 
     fi_neighbors = [neighbors;fi_neighbors] 
    end 
end 

第一個錯誤是,循環變量ij從不使用。因此它們是無用的(除了讓我們執行相同的計算m x n次)。讓我們把它們拿出來。

img = [0 0 0 0 0; 
     0 1 1 0 0; 
     0 0 0 0 0;]; 
[m n] = size(img) 
img = padarray(img, [2 2], 0) 
fi_neighbors = zeros(1,8); 

for r = 3:m 
    for c = 3:n 
     neighbors(1) = img(r-1,c-1); % Upper left. 
     neighbors(2) = img(r-1,c); % Upper middle. 
     neighbors(3) = img(r-1,c+1); % Upper right. 
     neighbors(4) = img(r,c-1); % left. 
     neighbors(5) = img(r,c+1); % right. 
     neighbors(6) = img(r+1,c+1); % Lower right. 
     neighbors(7) = img(r+1,c); % lower middle. 
     neighbors(8) = img(r+1,c-1); % Lower left.    
    end 
end 
fi_neighbors = [neighbors;fi_neighbors] 

隨着這些循環的方式進行,我們可以看到,你只更新fi_neighbors數組,你已經做了所有的計算後的一次。這就是爲什麼你之前得到相同結果m x n次。我們需要移動的循環,結果就是每個組計算後更新內部(我已經離開了這個設定的時間和僅列循環):

for r = 3:m 
    for c = 3:n 
     neighbors(1) = img(r-1,c-1); % Upper left. 
     neighbors(2) = img(r-1,c); % Upper middle. 
     neighbors(3) = img(r-1,c+1); % Upper right. 
     neighbors(4) = img(r,c-1); % left. 
     neighbors(5) = img(r,c+1); % right. 
     neighbors(6) = img(r+1,c+1); % Lower right. 
     neighbors(7) = img(r+1,c); % lower middle. 
     neighbors(8) = img(r+1,c-1); % Lower left.    
     fi_neighbors = [neighbors;fi_neighbors] %// moved inside loops 
    end 
end 

接下來是我們的循環範圍。您在每一邊填充了2個零的數組,因此您從行/列3開始。這很好,但你仍然在mn處結束循環。這意味着你處理(m-2) x (n-2)像素。你需要擴大範圍。但實際上,你的填充量超過了你的需要。每邊一個像素的填充就足夠了,所以讓我們一次都做,改變填充和糾正範圍:

img = [0 0 0 0 0; 
     0 1 1 0 0; 
     0 0 0 0 0;]; 
[m n] = size(img) 
img = padarray(img, [1 1], 0) 
fi_neighbors = zeros(1,8); 

for r = 2:m+1 
    for c = 2:n+1 
     neighbors(1) = img(r-1,c-1); % Upper left. 
     neighbors(2) = img(r-1,c); % Upper middle. 
     neighbors(3) = img(r-1,c+1); % Upper right. 
     neighbors(4) = img(r,c-1); % left. 
     neighbors(5) = img(r,c+1); % right. 
     neighbors(6) = img(r+1,c+1); % Lower right. 
     neighbors(7) = img(r+1,c); % lower middle. 
     neighbors(8) = img(r+1,c-1); % Lower left.    
     fi_neighbors = [neighbors;fi_neighbors] 
    end 
end 

現在你應該有一個工作計劃,讓你正確的輸出:

fi_neighbors = 

    0 0 0 0 0 0 0 0 <-- img(m,n) neighbors 
    1 0 0 0 0 0 0 0 
    1 1 0 0 0 0 0 0 
    0 1 1 0 0 0 0 0 
    0 0 1 0 0 0 0 0 
    0 0 0 0 0 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 0 0 0 0 
    0 0 0 0 0 0 0 1 
    0 0 0 0 0 0 1 1 
    0 0 0 0 0 1 1 0 
    0 0 0 0 0 1 0 0 <-- img(1,1) neighbors 
    0 0 0 0 0 0 0 0 

這可以工作,但看看我添加到輸出的筆記。結果的第一行包含像素img(m,n)的鄰居:圖像中的最後像素。倒數第二行包含img(1,1)的鄰居,最後一行由於您初始化爲zeros(1,8)而剛剛掛在那裏。所有這些對我來說都不自然,所以我要翻轉結果數組,以便img(1,1)是第一行。而且,在每個循環迭代中增長一個數組是很慢的。我們想要預分配數組,然後將數據放在適當的位置。

由於我們引用原始圖像中的像素,但是在填充圖像上計算,添加計數器變量比執行所有行/列索引計算容易得多,所以我添加了pix作爲計數器:

img = [0 0 0 0 0; 
     0 1 1 0 0; 
     0 0 0 0 0;]; 
[m n] = size(img); 
img = padarray(img, [1 1], 0) 
fi_neighbors = zeros(m*n,8); % preallocate result array 

pix = 0; % pixel counter 
for r = 2:m+1 
    for c = 2:n+1 
     pix = pix + 1; % find neighbors for next pixel 
     neighbors(1) = img(r-1,c-1); % Upper left. 
     neighbors(2) = img(r-1,c); % Upper middle. 
     neighbors(3) = img(r-1,c+1); % Upper right. 
     neighbors(4) = img(r,c-1); % left. 
     neighbors(5) = img(r,c+1); % right. 
     neighbors(6) = img(r+1,c+1); % Lower right. 
     neighbors(7) = img(r+1,c); % lower middle. 
     neighbors(8) = img(r+1,c-1); % Lower left. 
     fi_neighbors(pix,:) = neighbors; % update the correct row 
    end 
end 

結果:

fi_neighbors = 

    0 0 0 0 0 1 0 0 
    0 0 0 0 0 1 1 0 
    0 0 0 0 0 0 1 1 
    0 0 0 0 0 0 0 1 
    0 0 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 0 0 0 0 0 
    0 0 1 0 0 0 0 0 
    0 1 1 0 0 0 0 0 
    1 1 0 0 0 0 0 0 
    1 0 0 0 0 0 0 0 
    0 0 0 0 0 0 0 0 

現在,img(1,1)鄰居們都在第1行的img(m,n)鄰居們都行m * n個。

最後,您可以進行一些快速優化。他們都需要改變結果的順序。如果你願意以不同的順序呈現像素和鄰居,我將試圖清楚地表明,那麼我們可以首先改變循環的順序以利用MATLAB的列主要順序。

相反的:

for r = 2:m+1 
    for c = 2:n+1 
     ... 
    end 
end 

,我們將使用:

for c = 2:n+1 % be sure to swap m and n as well! 
    for r = 2:m+1 
     ... 
    end 
end 

對於大型矩陣,這應該與緩存保持我們正在當前列有幫助。這將改變像素的排序,以便代替第二像素是img(1,2),現在將是img(2,1),然後img(3,1),直到img(m,1),然後是img(1,2)

第二個變化凝聚所有的鄰居計算爲2行(也許3),但它改變,因爲我將在下面顯示的順序:

pix = 0; % pixel counter 
for c = 2:n+1 
    for r = 2:m+1 
     pix = pix + 1; % find neighbors for next pixel 

     neighbors = img(r-1:r+1,c-1:c+1); 
     neighbors = neighbors(:).'; 

     fi_neighbors(pix,:) = neighbors; % update the correct row 
    end 
end 

這需要的img子矩陣當前像素周圍,然後使用冒號表示將其轉換爲列向量,最後將其轉換爲行向量。下面是導致鄰居位置的內neighbors

neighbors(1) % Upper left. 
neighbors(2) % left. 
neighbors(3) % Lower left. 
neighbors(4) % Upper middle. 
neighbors(5) % *** current pixel *** 
neighbors(6) % Lower middle. 
neighbors(7) % Upper right. 
neighbors(8) % right. 
neighbors(9) % Lower right. 

但是現在我們已經在neighbors 9個元素包括當前像素!如果您確實不想列出當前像素,我們可以修復該問題,但無論哪種方式,我們都需要將fi_neighbors的大小更改爲(m*n,9)。如果需要,我們可以從結果中刪除第5列。

下面是最終代碼:

img = [0 0 0 0 0; 
     0 1 1 0 0; 
     0 0 0 0 0;]; 
[m n] = size(img); 
img = padarray(img, [1 1], 0); 
fi_neighbors = zeros(m*n,9); % preallocate result array 

pix = 0; % pixel counter 
for c = 2:n+1 
    for r = 2:m+1 
     pix = pix + 1; % find neighbors for next pixel 
     neighbors = img(r-1:r+1,c-1:c+1); 
     neighbors = neighbors(:).'; 
     fi_neighbors(pix,:) = neighbors; % update the correct row 
    end 
end 

fi_neighbors(:,5) = []; % OPTIONAL - remove current pixel from each row 

顯然,還有更多你可以做,但是這應該是一個很好的開始。

+0

您的示例矩陣僅包含「0」和「1」。你在哪裏得到'255'?請編輯您的問題以反映您的要求。 – beaker

+0

更新的輸入矩陣 – user1234

相關問題