我正在寻找一种在命令行上获取Bitwise XOR两个图像的方法(或以另一种方式在程序或脚本中实现)。
这将导致与支持它的图片编辑器中使用XOR混合模式相同的最终图片(Paint.NET,Photoshop等)
举个例子,假设我有图片A:
和图片B:
然后结果应该如下:
当然,有趣的是,当您再次使用图像B对图像C进行异或时,您将获得图像A的精确副本。
现在,我一直在互联网上查找以编程方式执行此操作的方法,但我一无所获。甚至ImageMagick也不支持对图像进行按位异或。
sombebody知道这样做的方法吗?
答案 0 :(得分:20)
ImageMagick可以做到这一点,虽然它有点复杂。一种方法是:
convert img1 img2 -fx "(((255*u)&(255*(1-v)))|((255*(1-u))&(255*v)))/255" img_out
(img1
,img2
,img_out
分别是两个输入和单个输出文件名。
这有点难看(我敢肯定有一个比我更多ImageMagick-fu的人可以清理它,但它的工作原理如下:
-fx "xxx"
基本上表示“对图片执行操作xxx
”。
在上面的表达式中,u
和v
分别代表第一和第二个输入图像。
现在,-fx
在按位运算符的方式中只有按位AND &
和按位OR |
。
要重建按位XOR,我们需要
convert img1 img2 -fx "(u & NOT v) | (NOT u & v)" img_out
要获取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
时,它会将范围u
中v
和[0,1]
中的所有像素标准化,而不是{{1}正如我们所期望的那样,并且对非整数螺丝做按位。
因此,我们必须将上述表达式中[0,255]
和u
的所有次数乘以255(因此按位运算工作),并除以在最后的255处返回ImageMagick期望的范围v
。
这为我们提供了原始命令
[0,1]
瞧!
答案 1 :(得分:11)
我发现图片上需要xor
,G'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
答案 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