web-dev-qa-db-ja.com

画像に対してビット単位のXOR)を実行する方法を探しています

コマンドラインで2つの画像の Bitwise XOR を取得する方法を探しています(またはプログラムやスクリプトで実装できる別の方法で)。

これにより、それをサポートする画像エディター(Paint.NET、Photoshopなど)でXORブレンディングモードを使用した場合と同じ最終画像が得られます)

例として、私が持っているとしましょう画像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)

もちろん、これの楽しい部分は、画像Cと画像Bを再びXORすると、画像Aの正確なコピーが得られることです。

今、私はこれをプログラムで行う方法をインターネット全体で探していましたが、何も見つかりませんでした。 ImageMagickでさえ、画像に対してビット単位のXORを実行することをサポートしていません。

誰かがこれを行う方法を知っていますか?

20
Qqwy

ImageMagickはそれを行うことができますが、少し複雑です。 1つの方法は次のとおりです。

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

img1img2img_outは、それぞれ2つの入力ファイル名と1つの出力ファイル名です)。

説明

それは少し醜いです(私よりも多くのImageMagick-fuを持っている人がそれをクリーンアップできると確信していますが、それは次のように機能します:

  1. -fx "xxx"は基本的に「画像に対して操作xxxを実行する」と言っています。上記の式で、uvは、それぞれ1番目と2番目の入力画像を表します。

  2. 現在、-fxはビット単位のAND&とビット単位の演算子の方法でビット単位のOR |のみを持っています。ビット単位のXORを再構築するには、

    convert img1 img2 -fx "(u & NOT v) | (NOT u & v)" img_out
    
  3. NOT(論理的なNOTはありますが、ビット単位のNOTはありません)を取得するには、NOT x = 255-xifxは8ビットです。したがって、NOT uを取得するには、画像uが8ビットであると仮定して、255-uを実行できます。したがって、ImageMagickコマンドは次のようになります。

    convert img1.png img2.img -fx "((255-u)&v)|(u&(255-v))" image_xor.png
    
    • ここでの1つの問題は、ImageMagickがfxを実行すると、[0,1]ではなく[0,255]の範囲のuvのすべてのピクセルが正規化されることです。私たちは期待しており、整数以外のネジをビット単位で実行すると、問題が発生します。

    • したがって、上記の式のuvallオカレンスに255を掛けて(ビット演算が機能するように)、除算する必要があります。 ImageMagickが期待する範囲[0,1]に戻るために、最後に255まで。

これにより、元のコマンドが得られます。

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

出来上がり!

22

画像に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

enter image description here

13
RobLabs

これが私がJavaで行う方法です:

2つの画像のすべてのピクセルを一度に繰り返します。 (forループ(y)内のforループ(x))。もちろん、BufferedImageを使用してください。次の手順でピクセルの色を取得できます。

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

他の画像についても同じことを行い、2つの色に対してxor演算を実行します。結果の値を、2つの入力画像と同じサイズの新しい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"));
5

自分でやりたい場合は、ピクセルごとに行います。ライブラリが必要な場合は、OpenCVをお勧めします。これは非常に素晴らしく、画像処理領域でサポートされている巨大な操作を備えたオープンソースライブラリです。 ^演算子を使用した直接[〜#〜] xor [〜#〜]をサポートします。幸運を。

2
Pervez Alam

知っています

A XOR B =(A AND NOT B)OR(NOT A AND B)。

そして、一般的な画像処理ツールのほとんどには、操作があり、操作がないので、残りは非常に簡単です:)

Pythonで作業すると、操作を実行し、それをプラグインとしてgimpに追加する簡単なスクリプトを作成できます;)

1
jlengrand

OpenCVには、bitwise_#を使用した画像とnumpy画像のすべての論理演算子があります。ここで#はxor、and、およびではなく...を参照してください。 OpenCV-2つのバイナリ画像間の交差

0
user1270710