web-dev-qa-db-ja.com

openCVでbitwise_and演算子は正確に何をしますか?

OpenCVで「bitwise_and」演算子を使用した場合の動作を正確には理解していませんでした。パラメータについても知りたいです。

6
Harit Ahuja

bitwise_and

2つの配列、または配列とスカラーの要素ごとのビット単位の結合を計算します。

パラメーター:

  • src1 –最初の入力配列またはスカラー。
  • src2 – 2番目の入力配列またはスカラー。
  • src –単一の入力配列。
  • value –スカラー値。
  • dst –入力配列と同じサイズとタイプの出力配列。
  • mask –オプションの操作マスク、8ビットのシングルチャネル配列。変更する出力配列の要素を指定します。

これがウェブ上にある例です: http://docs.opencv.org/trunk/d0/d86/tutorial_py_image_arithmetics.html

0

一般的な使用法は、通常「マスク」と呼ばれる、別のイメージによって定義されたイメージのサブセットを取得することです。

したがって、8x8の画像の左上の象限を「つかむ」と仮定します。次のようなマスクを作成できます。

_1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
_

Pythonを使用して上記の画像を生成できます:

_import numpy as np

mask = np.zeros(shape=(8,8), dtype=bool)
mask[0:4,0:4] = True
_

次に、次のような画像があるとします。

_1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
_

具体的には、上の画像がアメリカの国旗を単純化して表したものだと想像してください。左上の星、それ以外の場所の棒です。上の画像を作成したいとします。あなたは、マスクと、bitwise_andとbitwise_orを使ってあなたを助けることができます。

_imageStars = np.ones(shape=(8,8), dtype=bool)
for r, row in enumerate(imageStars):
    for c, col in enumerate(row):
        if r % 2 != c % 2: # even row, odd column, or odd row, even column
            imageStars[r,c] = False

imageBars = np.zeros(shape=(8,8), dtype=bool)
for r, row in enumerate(imageStars):
    if r % 2 == 0:
        imageBars[r,:] = True
_

これで星の画像ができました。

_1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1    
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1    
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1    
1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1
_

そしてバーの画像:

_1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
_

そして、それらを特定の方法で組み合わせて、旗を形成します。左上の象限の星と他のすべての場所のバーを使用します。

_imageStarsCropped = cv2.bitwise_and(imageStars, mask)
_

imageStarsCroppedは次のようになります。

_1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0    
1 0 1 0 0 0 0 0
0 1 0 1 0 0 0 0  
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
_

それがどのように形成されたかわかりますか? _bitwise_and_は、imageStarsが_1_ AND maskが_1_であるすべてのピクセルで_1_を返します。それ以外の場合は、_0_を返します。

では、imageBarsCroppedを取得しましょう。まず、マスクを逆にします。

_maskReversed = cv2.bitwise_not(mask)
_

_bitwise_not_は_1_を_0_に、_0_を_1_に変換します。 「ビットを反転」します。 maskReversedは次のようになります。

_0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
_

次に、maskReversedを使用して、必要なimageBarsの部分を「取得」します。

_imageBarsCropped = cv2.bitwise_and(imageBars, maskReversed)
_

imageBarsCroppedは次のようになります。

_0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
_

次に、2つの「トリミング」された画像を組み合わせてフラグを作成しましょう。

_imageFlag = cv2.bitwise_or(imageStarsCropped, imageBarsCropped)
_

imageFlagは次のようになります。

_1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 0 1 0 1 1 1 1
0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
_

なぜか分かりますか? _bitwise_or_は、常に_1_を返します_imageStarsCropped[r,c]==1_ OR _imageBarsCropped[r,c]==1_。

これがOpenCVのビット単位の操作を理解するのに役立つことを願っています。これらのプロパティは、コンピュータが算術を行うために2進数を使用したビット単位の演算と1対1で対応しています。

34
mannyglover