2016-05-23 71 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