OpenCVの核となる操作 - 画像の基本操作 + 画像の算術演算
画像に対する基本的な操作には、ピクセル値へのアクセスとその変更、ピクセル属性へのアクセス、対象領域の設定、画像チャネルの分割/結合などが含まれます。OpenCV でより最適化されたコードを作成したい場合は、OpenCV の使用に習熟することが非常に重要です。 Numpy (Numpy は高速配列計算用に最適化されたライブラリです)
1. 画像の基本操作
1.1 ピクセル値にアクセスして変更する
水平座標と垂直座標を通じてピクセル値にアクセスできます。BGR 画像の場合、青、緑、赤の値の配列が返されます (各色のピクセル値に対応) )、グレースケール画像の場合は、対応するグレースケールのみ
コード例
>>> import numpy as np
>>> import cv2 as cv
>>> img = cv.imread('messi5.jpg')
>>> px = img[100,100]
>>> print( px ) [157 166 200]
# 仅访问蓝色像素
>>> blue = img[100,100,0]
>>> print( blue )
157
もちろん、この方法でピクセル座標に値を直接割り当てて、ピクセル値を変更するという目的を達成することもできます。
Numpy は高速な配列計算用に最適化されたライブラリであると述べましたが、単に各ピクセルにアクセスして上記の方法のように変更するのは非常に遅く非効率であるため、この方法は使用されないことがよくあります。
しかし、領域内のピクセルを選択する必要がある場合、上記のメソッドは依然として非常に便利です。たとえば、最初の 4 行と最後の 5 列などを操作する必要があります。Numpy 配列には、arry という 2 つの配列メソッドが用意されています。 item() と arry.itemset()、これら 2 つのメソッドは単一の要素にアクセスするためによく使用されますが、常にスカラーを返します。
# 访问 RED 值
>>> img.item(10,10,2)
59
# 修改 RED 值
>>> img.itemset((10,10,2),100)
>>> img.item(10,10,2)
100
1.2 ピクセルのプロパティへのアクセス
画像の属性には、行、列、チャネルの数、画像のデータ型、ピクセル数などが含まれます。これらにアクセスしたいだけです。
画像の形状には、行、列、およびチャネル数のタプルを返す img.shape() を介してアクセスできます (画像がカラーの場合は、もちろん、単一チャネルのグレースケール画像である可能性もあります)。
総ピクセル数は、img.size() 関数の戻り値にアクセスすることで取得できます。
画像のデータ型は img.dtype() で取得します。
注: OpenCV-Python コードのバグの多くは無効なデータ型によって引き起こされるため、img.dtype() はデバッグ時に非常に重要です。
1.3 画像の関心領域 ROI を設定する
実際の演算処理では、人間の行動を分析して処理し、目的を達成するためにその人のいる範囲と1メートル以内の範囲を監視するなど、常に特定の領域を処理する必要があります。画像全体を検索することで、ROI が画像処理の精度とパフォーマンスを向上させます。
このコードは、ROI を画像の別の領域にコピーすることを実装します。
>>> ball = img[280:340, 330:390]
>>> img[273:333, 100:160] = ball
1.4 画像チャンネルの分割と結合
モノクロ チャネルを変更する必要がある場合がありますが、このときは、BGR 画像を 1 つのチャネルに分割するなど、画像チャネルのセグメント化と結合を使用します。
# 把BGR通道分别拆分在b,g,r
b,g,r = cv.split(img) # 拆分
>>> img = cv.merge((b,g,r)) # 合并(注意这里以元组的形式传参)
シングルチャネルピクセルの取得と変更
>>> b = img [:, :, 0]
>>> img [:, :, 2] = 0
# 注意这里元组中的0和2指的是通道索引
2. 画像の算術演算
このパートでは、画像に対するいくつかの算術演算 (加算、減算、ビット単位の演算) について説明します。これらの演算に関しては、まず次のことをマスターする必要があります: cv.add() と ** cv.addWeighted ()** これらの 2 つの関数関数は、次の関数を使用します。
2.1 画像の追加
画像の追加操作を実現するには 2 つの方法があります。1 つ目は、OpenCV の組み込み cv.add() 関数を直接使用することです。2 つ目は、Numpy ライブラリを使用して numpy を介して操作することです。追加されたイメージとして型を指定することも、2 番目のイメージを直接スカラーにすることもできます
注: ここで見落としがちな点がありますが、OpenCV と Numpy による画像加算の違いは、OpenCV の加算は飽和演算 (たとえば、ピクセルが 255 より大きい場合は 255 に等しくする) であるのに対し、OpenCV の加算は飽和演算であるのに対し、 Numpy 加算はモジュロ演算です (ピクセル加算が 255 より大きい場合、この値はモジュロ 255 である必要があります)
>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y ) # 250+10 = 260 % 256 = 4
[4]
OpenCV 関数の方が良い結果が得られることがわかりました。
2.2 画像の融合
画像融合は基本的には画像の加算ですが、加算に使用する画像に重み係数を設定することで、融合や透明化の効果を持たせることができます。
import cv2 as cv
import numpy as np
img1 = cv.imread(r'E:\image\wqw.png')
img2 = cv.imread(r'E:\image\qqq.png')
dst = cv.addWeighted(img1, 0.9, img2, 0.3, 0)
cv.imshow('dst', dst)
cv.waitKey(0)
cv.destroyAllWindows()
2.3 ビット単位の演算
ビット単位の演算には、ビット単位の AND、OR、NOT、および XOR 演算が含まれます。これらは、画像の任意の部分の抽出、非長方形の ROI の定義および処理などに役立ちます。
ビット単位の操作を学習するために引き続き例を使用します。画像に OpenCV ロゴを配置しますが、それは長方形ではないため、画像の処理に上記の画像の ROI を使用できません。今回はビット単位の操作が役に立ちました。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 加载两张图片
img1 = cv2.imread(r'E:\image\wqw.png')
img2 = cv2.imread(r'E:\image\opencv.png')
# 我想把logo放在左上角,所以我创建了ROI
# logo left top
rows, cols, channel = img2.shape
roi = img1[0: rows, 0: cols] # 获得bg
# mask of logo
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(mask)
# 现在将ROI中logo的区域涂黑
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
# 仅从logo图像中提取logo区域
img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
# 将logo放入ROI并修改主图像
dst = cv2.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst
cv2.imshow('res',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
えっと、なぜ私のプログラムでカットアウト効果を表示できないのかわかりませんが、コードの考え方は問題ないはずです
まず、メイン画像内のロゴを ROI として配置する領域を見つけてから、ロゴのマスクと反対側のマスクを見つけて、ROI 領域とロゴのマスクを AND 演算できるようにする必要があります。つまり、ROI に配置されるロゴです。次のステップでは、元の画像からマスクを通してロゴ領域を切り出します。切り出した後、切り出した Logp とロゴ画像の ROI を追加して、最終的なロゴ画像を取得します。元の画像の ROI は次のようになります。
(注: 記事の内容については、OpenCV4.1 の中国語公式ドキュメントを参照してください)
記事が役に立った場合は、ワンクリックと 3 つのリンクでサポートしてください。