画像処理パート5:算術、ビット単位、マスキング
画像処理シリーズの第5部では、Pythonにおける算術演算やビット演算、画像のマスキングについてさらに詳しく説明します。
ここでのマスク学習の冒険を始める前に、以前の記事を通して読むことをお勧めします。
環境を設定する
以下のコードは、下に示すすべてのアプリケーションで使用されます。ここにそれを含めるので、巨大なコードの塊を読む必要はありません。
散らかりを減らすのに役立ちます :)
importing numpy to work with pixels
import numpy as np
importing argument parsers
import argparse
importing the OpenCV module
import cv2
initializing an argument parser object
ap = argparse.ArgumentParser()
adding the argument, providing the user an option
to input the path of the image
ap.add_argument("-i", "--image", required=True, help="Path to the image")
parsing the argument
args = vars(ap.parse_args())
reading the image location through args
and reading the image using cv2.imread
image = cv2.imread(args["image"])
Pythonを使用した画像の算術演算
算術演算は、画像の多くの側面を向上させることを可能にします。
私たちは、ライティング、影、赤、青、緑の色の強調で作業できます。
アプリケーションの多くの画像フィルターは、写真を変更して美しくするために同じ方法を使用しています。
それでは、すべてのコードを始めましょう!
まず、制限が255または0を超えるかどうかを理解するために、255と0を提供する簡単なテストを実施できます。
printing out details of image min, max and the wrap around
print("max of 255 :", str(cv2.add(np.uint8([200]), np.uint8([100]))))
print("min of 0 :", str(cv2.subtract(np.uint8([50]), np.uint8([100]))))
print("wrap around :", str(np.uint8([200]) + np.uint8([100])))
print("wrap around :", str(np.uint8([50]) - np.uint8([100])))
この例では、画像内のすべてのピクセルの強度を100だけ増加させています。
adding pixels of value 255 (white) to the image
M = np.ones(image.shape, dtype="uint8") * 100
added = cv2.add(image, M)
cv2.imshow("Added", added)
cv2.waitKey(0)
これは、NumPyモジュールを使用して、私たちの画像と同じサイズの行列を構築し、それを私たちの画像に加えることで行われます。
画像を暗くしたい場合は、以下に示すように画像のピクセル値から値を減算します。
adding pixels of value 0 (black) to the image
M = np.ones(image.shape, dtype="uint8") * 50
subtracted = cv2.subtract(image, M)
cv2.imshow("Subtracted", subtracted)
cv2.waitKey(0)
これにより、元の画像の2つの異なるバリエーションが提供されるべきです。1つは明るいもので、もう1つは暗いものです。
ビット演算
私たちは画像をマスクする際に、ビット単位の操作を多く使います。
OpenCVのこの機能により、私たちに関連する画像の部分をフィルタリングすることができます。
設定中
ビット単位の操作を行うには、まず操作を行うための2つの変数または画像が必要です。
では、ビットwise演算を使用できるビットwiseの四角形とビットwiseの円を作成しましょう。
ビット単位の演算には画像が白黒である必要があることに注意してください。
creating a square of zeros using a variable
rectangle = np.zeros((300, 300), dtype="uint8")
cv2.rectangle(rectangle, (25, 25), (275, 275), 255, -1)
cv2.imshow("Rectangle : ", rectangle)
creating a circle of zeros using a variable
circle = np.zeros((300, 300), dtype="uint8")
cv2.circle(circle, (150, 150), 150, 255, -1)
cv2.imshow("Circle : ", circle)
受け取る出力画像はこのように見えるべきです。
AND 演算を使用して結合する
ビット単位の加算とは、2つの異なる画像の加算を指し、画像の各ピクセルに対してAND演算を使用して表示するものを決定します。
the bitwise_and function executes the AND operation
on both the images
bitwiseAnd = cv2.bitwise_and(rectangle, circle)
cv2.imshow("AND", bitwiseAnd)
cv2.waitKey(0)
円と四角のビットごとの加算は、次のような出力を生成します。
OR演算子を使用した選択肢が与えられた場合
ビットごとのORは、画像の各ピクセルにOR演算を実行することによって、2つの画像の積を提供します。
the bitwise_or function executes the OR operation
on both the images
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
cv2.waitKey(0)
ビット単位の論理和操作を実行すると、次のような結果が得られるはずです。
XOR演算による排他性
cv2モジュールによって提供されるもう一つの操作はXOR操作であり、これはbitwise_xor関数を通じて使用できます。
the bitwise_xor function executes the XOR operation
on both the images
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
cv2.imshow("XOR", bitwiseXor)
cv2.waitKey(0)
NOT演算を使用した否定
最後に、bitwise_not 関数を使用して行われる否定操作があります。
NOT演算は単一の画像だけを必要とし、ここでは何も加算したり減算したりしていません。
ここでもまだそれを使っていますが、それもまた選択肢です。
the bitwise_not function executes the NOT operation
on both the images
bitwiseNot = cv2.bitwise_not(rectangle, circle)
cv2.imshow("NOT", bitwiseNot)
cv2.waitKey(0)
この場合、円は四角の中にあり、そのため見ることができません。
Python OpenCVを使用した画像のマスキング
マスキングは画像処理で使用され、関心領域、つまり私たちが興味のある画像の部分を出力します。
マスキングにはビット単位の演算を使うことが多いです。これにより、必要ない画像の部分を除外することができます。
さあ、マスキングを始めましょう!
画像をマスクするプロセス
マスキングには三つのステップがあります。
- 画像と同じサイズの黒いキャンバスを作成し、それに
maskという名前を付けます。 - 画像に任意の図形を描き、その図形に白色を付けることで、マスクの値を変更する。
- マスクを使って画像にビット単位のADD操作を実行します。
同じプロセスに従って、いくつかのマスクを作成し、それらを画像に使用しましょう。
まず、長方形のマスクを使って作業しましょう。
creating a mask of that has the same dimensions of the image
where each pixel is valued at 0
mask = np.zeros(image.shape[:2], dtype="uint8")
creating a rectangle on the mask
where the pixels are valued at 255
cv2.rectangle(mask, (0, 90), (290, 450), 255, -1)
cv2.imshow("Mask", mask)
performing a bitwise_and with the image and the mask
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask applied to Image", masked)
cv2.waitKey(0)
では、円形マスクを使ってみましょう。
creating a mask of that has the same dimensions of the image
where each pixel is valued at 0
mask = np.zeros(image.shape[:2], dtype="uint8")
creating a rectangle on the mask
where the pixels are valued at 255
cv2.circle(mask, (145, 200), 100, 255, -1)
cv2.imshow("Mask", mask)
performing a bitwise_and with the image and the mask
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask applied to Image", masked)
cv2.waitKey(0)
もしすべてがうまくいけば、次のような出力を受け取るはずです。
結論
私たちはついに画像処理のコアに取り掛かり始めており、その中でビット演算とマスキングを理解することが重要です。
私たちが興味のある画像の部分だけを取り入れたり、特定の部分を排除したりするのに役立つので、非常に便利な概念です。
私たちは decent なペースで進んでいますが、もしあなたがタイムスキップして終わりに到達したいのであれば、どうぞ遠慮なく!
こちらは、OpenCVと顔認識に関する記事、およびAndroidとCameraX OpenCVのJava実装についてのものです。
参考文献
- 公式OpenCVウェブサイト
- OpenCVを使い始めるためのイントロダクション
- 私の画像処理用のGitHubリポジトリ
- 算術演算コード
- ビット演算コード
- マスキングコード






