2016-05-23 78 views
1

嗨我已經加載了一個圖像,從而創建一個3D矩陣。如何在3D矩陣中使用數組作爲索引?

img1 = imread('bluebird.jpg') 

我知道,對於一個載體,我可以創建基於邏輯測試的另一種載體和使用等載體作爲指數是這樣的:

speeds = [20 77 55 90 87 65 67 72 55] 
invalid = speed > 70 
speeds(invalid) = 0 

這將設置所有無效的速度speeds到0.

但我還沒有想出如何用3D矩陣(圖像)做到這一點。

我想要做的是爲藍色分量至少比三個分量(灰度)的平均值高出20%的每個像素交換顏色分量1(紅色)和3(藍色)。

我已經試過這樣:

img1 = imread('bluebird.jpg'); 
img2 = img1; 
m = mean(img1, 3); 
blues = img1(:,:,3) > 1.2*m; 
img2(blues, [3,2,1]) = img1(blues, [1,2,3]); 

但沒有奏效。變量藍調成功獲得我想要的像素(具有顯性藍色分量的像素),但在最後一行中出現非法語法。

是否有可能做我想要的東西?如果是這樣,怎麼樣?

在此先感謝。

回答

3

的問題是,因爲你的邏輯陣列是2D(需要關注前兩個維度),並且您的線性索引僅適用於第三維。你可以結合邏輯索引,但是你必須有一個每維一個數組。

data = magic(3); 
data([true false, true], [1 3]) 

% 8 6 
% 4 2 

解決這個一個簡單的方法爲你的情況是你的輸入重塑一個[M*N x 3]數組,然後你可以做你想要什麼,因爲你的邏輯陣列現在將長度M*N的列向量。

img1 = imread('bluebird.jpg'); 

% Remember the original size 
shape = size(img1); 

% Reshape to (M*N x 3) 
img2 = reshape(img1, [], 3); 

isBlue = img2(:,3) > 1.2 * mean(img2, 2); 
img2(isBlue, [3 2 1]) = img2(isBlue, [1 2 3]); 

% Reshape it back to the original size 
img2 = reshape(img2, shape); 

或者不使用索引,您可以簡單地調用fliplr

img1 = imread('bluebird.jpg'); 

% Remember the original size 
shape = size(img1); 

% Reshape to (M*N x 3) 
img2 = reshape(img1, [], 3); 

isBlue = img2(:,3) > 1.2 * mean(img2, 2); 
img2(isBlue, :) = fliplr(img2(isBlue, :)); 

% Reshape it back to the original size 
img2 = reshape(img2, shape); 

這將是比創建一個3D邏輯矩陣更好的性能,因爲reshape命令是非常便宜的,因爲他們並沒有真正改變的基礎數據。

1

邏輯索引(使用矩陣)和整數索引不能混用。 相反,你可以構建完整的邏輯索引矩陣:

img2 = rand(2, 4, 3); 
m = mean(img2, 3); 
blues = img2(:,:,3) > 1.2*m; 
f_ind = false(size(blues)); 
ind = cat(3, blues, f_ind, blues); 
img2(ind) = cat(3, img2(cat(3, f_ind, f_ind, blues)), img2(cat(3, blues, f_ind, f_ind))); 

,而不是最後兩行或者:

r_ind = cat(3, blues, f_ind, f_ind); 
b_ind = cat(3, f_ind, f_ind, blues); 
img2(b_ind) = img1(r_ind); 
img2(r_ind) = img1(b_ind); 
+0

第一個陳述其實並非如此。你不能合併邏輯*矩陣*和基於整數的索引。 – Suever

+0

@Suever謝謝澄清。並且'基於整數'也是正確的術語... – zeeMonkeez

1

用途:

[Y,X] = find(blues); 
inds1 = sub2ind(size(img1),Y,X,ones(length(Y),1)); 
inds2 = sub2ind(size(img1),Y,X,3*ones(length(Y),1)); 
img2([inds1,inds2]) = img1([inds2,inds1]); 
+0

嗨。我試過你的代碼,顯示的圖像與原始圖像相同。 – Jeff

+0

感謝您的評論,我修復了它(有一個小錯字) – drorco