Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
matlab中如何从矩阵中删除特定值_Matlab_Image Processing_Matrix - Fatal编程技术网

matlab中如何从矩阵中删除特定值

matlab中如何从矩阵中删除特定值,matlab,image-processing,matrix,Matlab,Image Processing,Matrix,我有图像矩阵420x700,我想删除每行中的特定值,更改图像尺寸。这就像从中删除一列,但不是直线,变成420x699图像。我应该水平保留删除值之前的值,并将删除值之后的所有值向后移动1个位置 RGB = imread('image.jpg'); I1 = RGB(:,:,1); 如何做到这一点?这是一个好问题,如果没有for循环,我想不出实现这一点的方法 假设M是要从中删除列的nr by nc矩阵,R是nr-by-1向量,每行上都有要删除的元素的列索引 以下代码创建了一个新的矩阵a,其中“列”

我有图像矩阵420x700,我想删除每行中的特定值,更改图像尺寸。这就像从中删除一列,但不是直线,变成420x699图像。我应该水平保留删除值之前的值,并将删除值之后的所有值向后移动1个位置

RGB = imread('image.jpg');
I1 = RGB(:,:,1);

如何做到这一点?

这是一个好问题,如果没有for循环,我想不出实现这一点的方法

假设
M
是要从中删除列的
nr by nc
矩阵,
R
nr-by-1
向量,每行上都有要删除的元素的列索引

以下代码创建了一个新的矩阵
a
,其中“列”从
M
中删除,向量
B
中删除了元素:

[nr,nc]=尺寸(M);
A=零(nr,nc-1,'like',M);
B=零(nr,1,'like',M);
对于k=1:nr
r=r(k);
t=[1:r-1,r+1:nc];
A(k,:)=M(k,t);
B(k)=M(k,r);
结束

@bicker和@Cris是正确的,但为了增加一些味道,我尝试演示另一种方法-使用线性索引,这可以在MATLAB中讲授有关二维数组的列主索引的有趣课程

另一点需要注意的是,这种过程是接缝雕刻算法中所遵循的,我们以这种方式移除垂直接缝

加载一个测试图像来运行它-裁剪它以便更容易地分析

I = imread('peppers.png');
I = I(100:100+9, 100:100+19, :);

figure, imshow(I)
创建指示要删除哪些像素的遮罩。这模拟了我认为您所指向的条件—在本例中,我们为要删除的每一行选择随机列索引。您可能会将此信息作为输入

mask = zeros(size(I, [1:2]), 'logical');
for idx = 1:size(mask, 1)
    randidx = randi(size(mask, 2));
    mask(idx, randidx) = 1;
end

figure, imshow(mask)
使用列主线性索引技巧可以更快地删除!因为我们一次删除一列,所以我们将图像旋转90度,并将此问题转化为一次删除一行。MATLAB“垂直”索引,因此我们可以使用线性索引一次删除所有遮罩像素(而不是一次删除一行/列),然后使用“重塑”恢复形状,最后旋转回原始方向

It = rot90(I);
maskt = rot90(mask);

% Preallocate output
Ioutput = zeros([size(I, 1), size(I, 2) - 1, size(I, 3)], 'like', I);

for nchannel = 1:3
    Icropped = It(:, :, nchannel);
    % MATLAB indexes column wise - so, we can use linear indexing to make
    % this computation simpler!
    Icropped = Icropped(maskt(:) == 0);
    Icropped = reshape(Icropped, [size(maskt, 1) - 1, size(maskt, 2)]);
    % Restore the correct orientation after removing element!
    Icropped = rot90(Icropped, 3);
    Ioutput(:, :, nchannel) = Icropped;
end

figure, imshow(Ioutput)

我裁剪了“辣椒”的图片来演示这一点,这样你就可以说服自己这是正确的。这种方法同样适用于较大的图像。

对于图像中的每一行
r
,将该行存储在临时数组中,删除所需元素,然后将修改后的数组复制到行
r
处的输出图像。我想您的操作与您描述的完全相同:对于每一行,将所选索引后的值向后移动1个位置。那么你就可以删除最后一列了。我认为这是不对的。您应该使用转置,而不是使用
rot90
,并且两次转置(前后)的成本远远超过在大型矩阵的行之间迭代的成本,所以这种方法实际上比使用for循环要慢。@JonathanH——我已经手动测试了旋转的想法——因为删除一列中的像素独立于其他列,所以旋转应该与转置相同。我们只需要将“方向”设置为“垂直”。我没有做过严格的性能测试,所以您可能是正确的w.r.t。传统的方法速度更快。因此,我在这里编辑/删除了答案中的性能声明。谢谢分享你的想法!感谢您在本例中提出了一种避免for循环的有趣方法!这是相当巧妙的,尽管这可能不是最有效的方法。:)