您好我已经加载了图像,因此创建了一个3D矩阵。
img1 = imread('bluebird.jpg')
我知道对于一个向量,我可以根据逻辑测试创建另一个向量,并将此另一个向量用作索引,如下所示:
speeds = [20 77 55 90 87 65 67 72 55]
invalid = speed > 70
speeds(invalid) = 0
这会将speeds
中的所有无效速度设置为0。
但我还没弄明白如何使用3D矩阵(图像)。
我想要做的是为每个像素交换颜色分量1(红色)和3(蓝色),其中蓝色分量比三个分量的平均值(灰度)至少高20%。
我试过这个:
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]);
但那没用。变量blues成功获得了我想要的像素(具有显性蓝色成分的像素),但我在最后一行得到了非法语法。
有可能做我想要的吗?如果是这样,怎么样?
提前致谢。
答案 0 :(得分: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 :(得分: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);
答案 2 :(得分: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]);