寻找一种在图像上进行按位异或的方法

时间:2011-12-14 12:57:54

标签: image image-processing imagemagick xor

我正在寻找一种在命令行上获取Bitwise XOR两个图像的方法(或以另一种方式在程序或脚本中实现)。

这将导致与支持它的图片编辑器中使用XOR混合模式相同的最终图片(Paint.NET,Photoshop等)

举个例子,假设我有图片A:

Image A(Seattle, from the paint.net documentation

图片B:

ImageB(Apple, from the paint.net documentation)

然后结果应该如下:

Image C(Xor result of above images, from the paint.net documentation)

当然,有趣的是,当您再次使用图像B对图像C进行异或时,您将获得图像A的精确副本。

现在,我一直在互联网上查找以编程方式执行此操作的方法,但我一无所获。甚至ImageMagick也不支持对图像进行按位异或。

sombebody知道这样做的方法吗?

6 个答案:

答案 0 :(得分:20)

ImageMagick可以做到这一点,虽然它有点复杂。一种方法是:

convert img1 img2 -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out

img1img2img_out分别是两个输入和单个输出文件名。

说明

这有点难看(我敢肯定有一个比我更多ImageMagick-fu的人可以清理它,但它的工作原理如下:

  1. -fx "xxx"基本上表示“对图片执行操作xxx”。 在上面的表达式中,uv分别代表第一和第二个输入图像。

  2. 现在,-fx在按位运算符的方式中只有按位AND &和按位OR |。 要重建按位XOR,我们需要

    convert img1 img2 -fx "(u & NOT v) | (NOT u & v)" img_out
    
  3. 要获取NOT(有一个逻辑NOT但没有按位NOT),我们会记住NOT x = 255-x if x是8位。 因此,为了获得NOT u我们可以255-u,假设图像u是8位。 因此,ImageMagick命令将是:

    convert img1.png img2.img -fx "((255-u)&v)|(u&(255-v))" image_xor.png
    
    • 这里的一个问题是,当ImageMagick执行fx时,它会将范围uv[0,1]中的所有像素标准化,而不是{{1}正如我们所期望的那样,并且对非整数螺丝做按位。

    • 因此,我们必须将上述表达式中[0,255]u所有次数乘以255(因此按位运算工作),并除以在最后的255处返回ImageMagick期望的范围v

  4. 这为我们提供了原始命令

    [0,1]

    瞧!

答案 1 :(得分:11)

我发现图片上需要xorG'MIC工具适合我。 G' MIC非常强大,Image Magick也是如此,但值得一试解决一些棘手的图像处理问题。

gmic a.png b.png -blend xor -o result.png

G' MIC也直接用于上面发布的图像。

gmic http://i.stack.imgur.com/Ws6e8.png http://i.stack.imgur.com/hoBIM.png -blend xor -o result.png

求助,

gmic -h -blend

enter image description here

答案 2 :(得分:5)

以下是我在Java中的表现:

一次迭代两个图像的所有像素。 (for循环(y)中的循环(x))。当然,使用BufferedImage。您可以通过执行以下操作获取像素的颜色:

int color = img.getRGB(x, y);

对其他图像执行相同操作,并对两种颜色执行xor操作。将结果值存储在与两个输入图像具有相同尺寸的新BufferedImage中。

以下是一些示例代码:

public static BufferedImage xorEffect(BufferedImage imageA, BufferedImage imageB) {
    if (imageA.getWidth() != imageB.getWidth() ||
        imageA.getHeight() != imageB.getHeight())
    {
        throw new IllegalArgumentException("Dimensions are not the same!");
    }
    BufferedImage img = new BufferedImage(imageA.getWidth(),
                                          imageA.getHeight(),
                                          BufferedImage.TYPE_INT_ARGB_PRE);

    for (int y = 0; y < imageA.getHeight(); ++y) {
        for (int x = 0; x < imageA.getWidth(); ++x) {
           int pixelA = imageA.getRGB(x, y);
           int pixelB = imageB.getRGB(x, y);
           int pixelXOR = pixelA ^ pixelB;
           img.setRGB(x, y, pixelXOR);
        }
    }
    return img;
}

要从文件中加载图像,请使用:

BufferedImage imageA = ImageIO.read(new File("/home/username/image.png"));

答案 3 :(得分:2)

如果您想自己做,请逐像素进行。 如果你想要一个图书馆,我推荐OpenCV。这是一个非常好的开源库,在图像处理领域支持大量操作。它支持使用^运算符直接 XOR 。 祝你好运。

答案 4 :(得分:1)

知道

XOR B =(A而非B)或(不是A和B)。

并且大多数常见的图像处理工具都有,而且,或者不是操作,其余的很容易:)

在Python中工作,你可以有一个简单的脚本来执行操作,甚至可以将它作为插件添加到gimp中;)

答案 5 :(得分:0)

OpenCV使用bitwise_#在图像和numpy图像上拥有所有逻辑运算符#哪里#可以是xor,和,而不是...见OpenCV - Intersection between two binary images