检查图像是否相同

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

[好,所以我正在编写一个读取两个图像并确定图像是否相同的函数。它必须检查两件事:

1. The dimensions are the same
2. The dimensions are the same, but the picture itself is different

如果是第二种情况,那么我需要我的函数在图像像素相同的情况下输出白色,在图像像素不同的情况下输出黑色。这应该很简单,但是由于某种原因,我正在努力。如果图片相同,那么我希望它读出“图片相同”。如果尺寸不同,那么我要说“图像的尺寸不同”。如果尺寸匹配,但图片不同,则:

(1) Create an output image that highlights the differences between the
two images. This image should be exclusively black and white, where it
is white everywhere that the two images have the same RGB values, but
black wherever the RGB values of the images differ. This image should
be named by the following naming convention:
'<imageName1>_vs_<imageName2>.png.'
(2) Output the string 'The RBG values are different: see %s.',
where you should print the name of your output file into the '%s'

我有前两个案例。这是我遇到的第三个问题。我只得到一张白色的图片。

Test case:
oranges :http://tinypic.com/r/2072gaq/8
tangerines: http://tinypic.com/r/2ufy2bn/8
Solution: http://tinypic.com/r/nqvbep/8
out3 = checkImage('oranges.png', 'tangerines.png');
oute => 'The RGB values are different: see oranges_vs_tangerines.png.'
      - oranges_vs_tangerines.png should look like
        oranges_vs_tangerines_soln.png

这是我到目前为止所拥有的:

function[comparison] = checkImage(pic1,pic2)
%// Reads in the images
img1 = imread(pic1);
img2 = imread(pic2);

%//Extracts the layers for both pictures
red1 = img1(:,:,1);
green1  = img1(:,:,2);
blue1 = img1(:,:,3);

red2 = img2(:,:,1);
green2 = img2(:,:,2);
blue2 = img2(:,:,3);

%// Finds the dimensions of both pictures
[r1, c1, l1] = size(img1);
[r2, c2, l2] = size(img2);

%// My lovely comparison loop
if size(img1) == size(img2)  
%// Subcase to check if image is the same
    if red1 == red2 & green1 == green2 & blue1 == blue2
    comparison = 'The images are the same';
%//Something down here has to be wrong
    elseif red1 ~= red2 & green1 == green2 & blue1 == blue2
            red = 0;
            green = 255;
            blue = 255;
    elseif red1 ~= red2 & green1 ~= green2 & blue1 == blue2
            red = 0;
            green = 0;
            blue = 255;
    elseif red1 ~= red2 & green1 ~= green2 & blue1 ~= blue2
            red = 0;
            green = 0;
            blue =0;
    elseif red1 == red2 & green1 ~= green2 & blue1 == blue2
            red = 255;
            green = 0;
            blue = 255;
    elseif red1 == red2 & green1 ~= green2 & blue1 ~= blue2
            red = 255;
            green = 0;
            blue = 0;
    else
        red = 255;
        green = 255;
        blue = 0;
%// This part could be the issue, but I am unsure
         newpic = cat(3,red,green,blue);
          name1 = pic1(1:end-4);
          name2 = pic2(1:end);
          picture = [name1 '_vs_' name2];
          imwrite(newpic,picture);
         comparison = sprintf('The RBG values are different: see %s.',picture);
    end   
       %// This appears to work fine 
elseif r1 & c1 & l1 ~= r2 & c2 & l2
    comparison = 'The images have different dimensions.';
else %// I put this in for S&G
         comparison = 'My code is wrong';  
end
end

我非常感谢您的帮助/建议。我认为我使此代码过于复杂。

编辑:我意识到我已经用我的代码纠正了这些值,但是实际上我并没有写它们。就像,它不知道如何将颜色放置在不匹配的地方。我知道我知道该怎么做。我只需要加倍努力。

尝试两个:

function[comparison] = checkImage(pic1,pic2)
img1 = imread(pic1);
img2 = imread(pic2);

red1 = img1(:,:,1);
green1  = img1(:,:,2);
blue1 = img1(:,:,3);

red2 = img2(:,:,1);
green2 = img2(:,:,2);
blue2 = img2(:,:,3);

[r1, c1, l1] = size(img1);
[r2, c2, l2] = size(img2);

mask1 = red1 ~= red2 & green1 == green2 & blue1 == blue2;
mask2 = red1 ~= red2 & green1 ~= green2 & blue1 == blue2;
mask3 = red1 ~= red2 & green1 ~= green2 & blue1 ~= blue2;
mask4 = red1 == red2 & green1 ~= green2 & blue1 == blue2;
mask5 = red1 == red2 & green1 ~= green2 & blue1 ~= blue2;
mask6 = red1 ~= red2 & green1 ~= green2 & blue1 ~= blue2;

color1 = [red1 green1 blue1];
color2 = [red2 green2 blue2];
if size(img1) == size(img2) 
    if red1 == red2 & green1 == green2 & blue1 == blue2
    comparison = 'The images are the same';
    elseif mask1 == 1
            red1(mask1) = 0;
            green1(mask1) = 255;
            blue1(mask1) = 255;
    elseif mask2 == 1
            red1(mask2) = 0;
            green1(mask2) = 0;
            blue1(mask2) = 255;
    elseif mask3 == 1
            red1(mask3) = 0;
            green1(mask3) = 0;
            blue1(mask3) =0;
    elseif mask4 == 1
            red1(mask4) = 255;
            green1(mask4) = 0;
            blue1(mask4) = 255;
    elseif mask5 == 1
            red1(mask5) = 255;
            green1(mask5) = 0;
            blue1(mask5) = 0;
    else
        red1(mask6) = 255;
        green1(mask6) = 255;
        blue1(mask6) = 0;
         newpic = cat(3,red1,green1,blue1);
          name1 = pic1(1:end-4);
          name2 = pic2(1:end);
          picture = [name1 '_vs_' name2];
          imwrite(newpic,picture);
         comparison = sprintf('The RBG values are different: see %s.',picture);
    end   

elseif r1 & c1 & l1 ~= r2 & c2 & l2
    comparison = 'The images have different dimensions.';
else 
         comparison = 'My code is wrong';  
end

end
image matlab image-processing
1个回答
2
投票

好,让我们简化问题描述...主要是因为它可以使我更快地回答问题,并使我对需要做的事情有更好的了解:

给出两个图像:

  1. 我们需要检查两个尺寸是否相同。
  2. 如果尺寸匹配,那么我们需要检查两个图片是否完全相同。如果是,那么我们将输出图像相同。
  3. 如果不是,那么您需要遍历两个图像的每个像素,然后以白色标记该位置是否具有相同的RGB值,或者以黑色标记它们是否具有相同的值。

而且,您还提供了示例图像和基本事实:

图像#1

图像2

地面真相(可爱!)

请注意,图像是使用JPEG量化的,因此由于量化噪声,您不会获得完全相同的输出。您到处都会出现一些虚假像素,但整体图片应该看起来相同。


假设图像以img1img2的形式加载。

img1 = imread('http://oi59.tinypic.com/2072gaq.jpg');
img2 = imread('http://oi58.tinypic.com/2ufy2bn.jpg');

首先,让我们检查尺寸是否相同:

img1Rows = size(img1, 1);
img1Cols = size(img1, 2);
img2Rows = size(img2, 1);
img2Cols = size(img2, 2);

if (img1Rows ~= img2Rows) || (img1Cols ~= img2Cols)
    disp('Image dimensions are not the same');
    return;
end

上面的代码读取每个图像的尺寸(行和列),并检查两个图像的行和列是否匹配。如果没有,我们输出它们的尺寸不相同,然后退出。

现在,如果它们相同,那么让我们检查一下图像是否完全相同。我建议您采取的措施是拍摄每张图像,并对它们进行整形,以使其适合单个矢量。完成此操作后,逐点进行求和,然后将所有这些求和相加。如果图像exactly相同,则所有差异的总和将为零。我还将将图像转换为double精度,以允许出现负差。不知道是否涵盖了数据类型,但是图像通常是无符号的8位整数,这意味着数字的有效范围在[0,255]之间。任何低于0的值都将被裁剪为0,而任何大于255的值都将被裁剪为255。因此,如果您执行了0 - 1并且它是无符号的8位整数,则将其注册为0的差,这是不正确的。因此,让我们将图像转换为double,并采用absolute值,以确保不会出现负数和正数相抵消而导致零和的情况。因此:

img1_double = double(img1);
img2_double = double(img2);
if sum( abs( img1_double(:) - img2_double(:) ) ) == 0.0
    disp('The images are the same');
    return;
end

现在,我们进入图像内容不同的情况。我要做的是提取每个颜色平面,然后执行一个巨大的相等运算符,以查看我们在相应位置是否具有相同的RGB值。换句话说:

out = (img1(:,:,1) == img2(:,:,1)) & (img1(:,:,2) == img2(:,:,2)) & (img1(:,:,3) == img2(:,:,3));
out = 255*uint8(cat(3,out,out,out));

这基本上检查图像在相应位置是否具有相同的RGB值。这将产生一个二进制图像,该图像指示我们上面定义的标准。因为您需要返回彩色图像,所以我们只需要在三维空间中将图像复制3次,转换为uint8,然后乘以255,即可将其转换为RGB图像。

您还可以做的是将其修饰为for循环。首先分配全为逻辑true的图像,然后为每个图像提取成对的色平面,找到每个色平面相等的位置,然后对结果进行逻辑“与”运算并将其附加到out。我们基本上实现了与上述相同的操作,但是更加紧凑。因此:

out = true(size(img1,1), size(img1,2));
for p = 1 : 3
    img1_plane = img1(:,:,p);
    img2_plane = img2(:,:,p);
    out = out & (img1_plane == img2_plane);
end
out = 255*uint8(cat(3,out,out,out));

如果用imshow(out);显示此图像,则会得到:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9uQnJSMi5wbmcifQ==” alt =“在此处输入图像描述”>

甜。现在,我们要做的就是显示适当的消息。您已经在上面的代码中完成了此操作。现在,如果我们要将所有内容包装成一个不错的函数,我们可以这样做:

function [comparison] = checkImage(pic1,pic2)
   img1 = imread(pic1);
   img2 = imread(pic2);

   img1Rows = size(img1, 1);        
   img1Cols = size(img1, 2);
   img2Rows = size(img2, 1);
   img2Cols = size(img2, 2);

   if (img1Rows ~= img2Rows) || (img1Cols ~= img2Cols)
       comparison = 'Image dimensions are not the same';
       return;
   end

   img1_double = double(img1);
   img2_double = double(img2);
   if sum( abs( img1_double(:) - img2_double(:) ) ) == 0.0
       comparison = 'The images are the same';
       return;
   end

   out = (img1(:,:,1) == img2(:,:,1)) & (img1(:,:,2) == img2(:,:,2)) & (img1(:,:,3) == img2(:,:,3));

   % // OR
   %out = true(size(img1,1), size(img1,2));
   %for p = 1 : 3
   %    img1_plane = img1(:,:,p);
   %    img2_plane = img2(:,:,p);
   %    out = out & (img1_plane == img2_plane);
   %end
   out = 255*uint8(cat(3,out,out,out));
   picture = [pic1(1:end-4) '_vs_' pic2(1:end-4) '.png'];
   imwrite(out, picture);
   comparison = sprintf('The RGB values are different: see %s.',picture);

请注意最后三行代码。通过为两个图像名称提取最后四个字符,然后提取所有内容,然后在中间放置_vs_字符串,并在末尾附加.png,来创建将要保存图像的字符串字符串。我们还将存储在out中的该二进制图像写入文件。我还更改了disp语句,将字符串写入comparison,就像您将其放入函数中一样。这是在函数中返回的字符串,但副作用是,我们也按照该命名约定将图像写入文件。


开心!

© www.soinside.com 2019 - 2024. All rights reserved.