如何更改Matlab代码以使imshow()函数显示正确的颜色?

问题描述 投票:0回答:2

我写了一个简单的Matlab代码,它加载图像并在x轴和y轴上进行平移。如果图像应在x轴上翻译10个像素,我用0填充前10列,将所有列向右移动10个单位,并将图片右侧切10个像素。当我输入正x值时,加载的图片不再显示正确的颜色(它具有负值),尽管当我将它们打印到屏幕时RGB值是正确的!

我已经在互联网上看过,imshow()做了某种缩放,但这并没有真正帮助我。

所以这是代码:

clear;
clc;

picture_in = imread('landscape.jpg');    %load picture
[P,Q,RGB]=size(picture_in);              %obtain size of dimension

%Translation
tx=2;
ty=0;

k=0;
j=0;
h=0;
while k<Q
    j=0;
    while j<P
        h=0;
        while h<RGB
            if (round(k+1-tx)>0)&&(round(k+1-tx)<=Q)&&(round(j+1+ty)>0)&&(round(j+1+ty)<=P) 
                picture_out(j+1,k+1,h+1)=picture_in(round(j+1+ty),round(k+1-tx),h+1);
            else
                picture_out(j+1,k+1,h+1)=0;
            end

            h=h+1;
        end
        j=j+1;
    end
    k=k+1;
end
picture_out;
imagesc(picture_out);

我真的很感激这里的一些帮助。正如我已经提到的: - 如果平移是负的,那么颜色是正确的 - 当我看到一个小图像(例如,10x10)的张量移动了2个像素然后我可以看到前两个列是0以下列包含它们应包含的值。所以我猜这是一个imshow()的问题

编辑(附加注释):输出图像的RGB值只有0或255,但两者之间没有任何值。

matlab image-processing imshow
2个回答
0
投票

您的代码适合我。

你遇到的一个问题是你没有预先分配picture_out。它在您第一次为其赋值时创建,并在每次为其分配另一个值时进行扩展。您分配给它的第一个值决定了它的类型。如果你指定0(一个double),它将成为一个double数组。如果你从picture_in(一个uint8)中分配一个值,它将成为一个uint8数组。根据您移动图像的方向,将发生一个或另一个。

uint8图像的值为0-255。这些是您的输入值。 double图像可以存储几乎任何幅度的值,但MATLAB总是假设这样的图像具有0-1范围内的值。因为你将0-255范围内的值放入double数组中,所以当你调用imagesc时,MATLAB会假设任何大于1的数据都是1,因此会显示一个全白图像。

因此,当您向左移动图像时,您将获得uint8输出图像,并且它将正确显示。当您向右移动图像时,您将获得一个double输出图像,它将显示所有白色。

解决方案是在循环之前正确分配数组:

picture_out = zeros(size(picture_in),'uint8');

这将进一步加快您的代码速度。


Unsolicited advice:

你应该学会使用for循环,它们比while循环容易得多。代替:

k=0;
while k<Q
    % do something
    k=k+1;
end

你得到

for k = 1:Q
    % do something
end

另外,在k=0中,不是从k<Q循环,而是在MATLAB中,从k=1循环而不是k<=Q,如上面的for循环更自然。


但是,在许多情况下,您根本不需要循环。您的代码可以更有效地重写

picture_out = zeros(size(picture_in),'uint8');
picture_out(:,1+tx:end,:) = picture_in(:,1:end-tx,:);

(对于tx>0;你可以改变索引以换向另一种方式。)


或者,使用circshift

picture_out = circshift(picture_in,tx,2);

在这里,tx也可能是负面的。


0
投票

所以我玩了一段时间的代码并发现如果我不手动将0放在else子句中,而是从图片张量中取出它:

else
                picture_out(j+1,k+1,h+1)=picture_in(1,1,1);

一切正常。深入挖掘我发现我可以手动输入值,但我需要将它们作为uint8()变量放入。

如果我像这样更改else子句,代码最终会起作用:

else
                picture_out(j+1,k+1,h+1)=uint8(0);
© www.soinside.com 2019 - 2024. All rights reserved.