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

时间:2019-04-20 04:46:45

标签: matlab image-processing imshow

我编写了一个简单的Matlab代码,该代码可加载图像并在x轴和y轴上进行平移。如果图像应在x轴上平移10个像素,则我将前10列填充为0,将所有列向右移动10个单位,然后将图片的右侧剪切10个像素。当我输入正的x值时,虽然将RGB值打印到屏幕上时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,而中间没有。

2 个答案:

答案 0 :(得分:0)

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

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);

答案 1 :(得分: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');

这还将加快代码的速度。


主动提供的建议:

您应该学习使用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

(对于picture_out = circshift(picture_in,tx,2); ;您可以将索引更改为其他方式。)


或者,使用circshift

tx

在这里,var workbook = new ExcelJS.Workbook(); var worksheet = workbook.addWorksheet('Worksheet name'); var imageId2 = workbook.addImage({ filename: url + 'images/403.png', extension: 'png', }); worksheet.addImage(imageId2, 'H12:N12'); var buff = workbook.xlsx.writeBuffer().then(function(data) { var blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); saveAs(blob, compname + ".xlsx"); }); 也可以为负。