記事のディレクトリ
OpenCV-Python:コアオペレーション
9画像の基本操作
目標
•ピクセル値の取得と変更
•画像属性(情報)の取得
•画像ROI()
•画像チャネルの分割とマージ
これらの操作のほとんどすべては、OpenCVよりもNumpyと密接な関係があるため、Numpyヘルプに慣れることができますパフォーマンスの高いコードを記述します。
(例のほとんどは1行のコードしかないため、例はPythonターミナルに表示されます)
9.1ピクセル値の取得と変更
まず、画像を読み込む必要があります。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
ピクセルの行と列の座標に基づいてピクセル値を取得できます。BGRイメージの場合、戻り値はB、G、Rの値です。グレースケール画像の場合、グレースケール値(明るさ?強度)を返します。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
px=img[100,100]
print(px)
blue=img[100,100,0]
print(blue)
同様の方法でピクセル値を変更できます。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
img[100,100]=[255,255,255]
print(img[100,100])
# [255 255 255]
警告:Numpyは、高速行列演算用に最適化されたソフトウェアパッケージです。したがって、ピクセル値を1つずつ取得して1つずつ変更することはお勧めしません。これは非常に遅くなります。行列演算を実行できる場合は、ループを使用しないでください。
注:上記の方法は、マトリックスの領域(たとえば、最初の5行と最後の3列)を選択するために使用されます。各ピクセルの値を取得するには、Numpyのarray.item()とarray.itemset()を使用する方がよいでしょう。ただし、戻り値はスカラーです。B、G、Rのすべての
値を取得する場合は、array.item()を使用してそれらを分割する必要があります。
ピクセル値を取得して変更するためのより良い方法。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
print(img.item(10,10,2))
img.itemset((10,10,2),100)
print(img.item(10,10,2))
# 59
# 100
9.2画像属性を取得する
画像の属性には、行、列、チャネル、画像データ型、ピクセル数などが含まれます。img.shapeは画像の形状を取得できます。彼の戻り値は、行、列、およびチャネルの数を含むタプルです。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
print(img.shape)
#(342, 548, 3)
注:画像がグレースケール画像の場合、戻り値は行と列の数のみです。したがって、この戻り値をチェックすることで、ロードされた画像がグレースケール画像であるかカラー画像であるかを知ることができます。
img.sizeは、画像のピクセル数を返すことができます。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
print(img.size, img.dtype) # 返回的是图像的数据类型.
# 562248 uint8
# uint8*
注:img.dtypeは、デバッグ時に非常に重要です。OpenCVPythonコードのデータ型にはしばしば矛盾があるためです。
9.3画像のROI
画像の特定の領域を操作する必要がある場合があります。たとえば、画像内の目の位置を検出する場合は、画像内で直接検索するのではなく、最初に画像内の顔を見つけてから、顔領域で目を見つける必要があります。これにより、プログラムの精度とパフォーマンスが向上します。
ROIは、Numpyインデックスを使用して取得することもできます。次に、ボールの部分を選択して、画像の他の領域にコピーします。
import cv2
import numpy as np
img=cv2.imread('messi5.jpg')
ball=img[280:340,330:390]
img[273:333,100:160]=ball
img=cv2.imshow('test', img)
cv2.waitKey(0)
結果を見てください:
9.4画像チャンネルの分割とマージ
3つのBGRチャネルを別々に操作する必要がある場合があります。これは、BGRを単一のチャネルに分割するために必要なものです。場合によっては、独立したチャネルの画像を1つのBGR画像にマージする必要があります。あなたはこれを行うことができます:
import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b,g,r=cv2.split(img)
img=cv2.merge(b,g,r)
または:
import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b=img[:,:,0]
すべてのピクセルの赤チャネル値を0にしたい場合は、分割してから値を割り当てる必要はありません。Numpyインデックスを直接使用できます。これにより、高速になります。
import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
img[:,:,2]=0
警告:cv2.split()は時間のかかる操作です。本当に必要な場合にのみ使用し、Numpyインデックスを使用できる場合は使用してみてください。
9.5画像の拡大(塗りつぶし)
フォトフレームのように画像の周囲に境界線を作成する場合は、cv2.copyMakeBorder()関数を使用できます。これは、畳み込み演算またはゼロパディングでよく使用されます。この関数には、次のパラメータが含まれています。
•src入力画像
•上、下、左、右の境界に対応するピクセル数。
•borderTypeは、そのタイプの境界線を追加します。タイプは次のとおりです。
-cv2.BORDER_CONSTANTは、色付きの定数値の境界線を追加します。次のパラメーター(値)が必要です。
–cv2.BORDER_REFLECT境界要素の鏡像。例:fedcba | abcde-fgh | hgfedcb
– cv2.BORDER_REFLECT_101またはcv2.BORDER_DEFAULTは上記と同じですが、わずかに変更されています。次に例を示します。gfedcb| abcdefgh | gfedcba
–cv2.BORDER_REPLICATEは最後の要素を繰り返します。例:aaaaaa | abcdefgh | hhhhhhh
– cv2.BORDER_WRAP次のように、何を言うべきかわかりません:cdefgh | abcdefgh | abcdefg
•境界線の種類がcv2.BORDER_CONSTANTの場合、値の境界線の色
これらのタイプをよりよく理解するには、以下のデモプログラムを参照してください。
import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE=[255,0,0]
img1=cv2.imread('opencv_logo.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
結果は次のとおりです(matplotlibは描画に使用されるため、RとBの位置が交換されます。OpenCVではBGRで配置され、matplotlibではRGBで配置されます)。
詳細については、公式アカウントに注意してください。