はじめに
画像データを1色に塗りつぶす方法について解説します。
画像の塗りつぶしは画像データの初期化などで利用する機会が多いと思いますが、本投稿で画像データの初期化時に行う方法と初期化をした後に行う方法について紹介します。
初期化の時に塗りつぶす
初期化時に画素を全て同じ値に塗りつぶして画像を作成する場合、NumPyの機能を用います。
全てを”0”(黒)で初期化する方法と、任意の色で初期化する方法の2種類があります。
Numpy.zeros関数
画素値を0で初期化します。全ての画素値が0になるので黒く塗りつぶされた画像が作成されます。
引数
名称 | 説明 |
shape(必須) | 画像データのshape |
dtype(オプション) | データ型, デフォルト値はfloat |
order(オプション) | 'C'または'F', デフォルト値は'C'。 メモリへの格納を行優先(C-style)または列優先(F-style)の指定 |
使い方
RGBのカラー画像として作成する場合のコードです。
引数の画像データのshapeは横方向のピクセル列,縦方向のピクセル行,チャンネル数のtupleとなるので、RGBのカラー画像のの場合、3つ目のチャンネル数は"3"となります。
import cv2 import numpy as np # NumPyに"np"という省略名をつける # 画像のサイズを指定 width = 200 # 幅 height = 100 # 高さ # RGBの画像として作成して、画素の全てを0で埋める(黒く塗りつぶす)。データ型は符号なし8ビット整数を指定。 color_image = np.zeros((height, width, 3), np.uint8)
グレースケール画像として作成する場合のコードです。
引数の画像データのshapeのチャンネル数はグレースケール画像なので"1"となります。
import cv2 import numpy as np # NumPyに"np"という省略名をつける # 画像のサイズを指定 width = 200 # 幅 height = 100 # 高さ # グレースケールの画像として作成して、画素の全てを0で埋める(黒く塗りつぶす)。データ型は符号なし8ビット整数を指定。 gray_image = np.zeros((height, width, 1), np.uint8)
Numpy.full関数
画素値を任意の色で初期化します。
引数
名称 | 説明 |
shape(必須) | 画像データのshape |
fill_value(必須) | 初期値(色)の指定 |
dtype(オプション) | データ型, デフォルト値はfill_valueと同じデータ型 |
order(オプション) | 'C'または'F'。 メモリへの格納を行優先(C-style)または列優先(F-style)の指定。 (デフォルト:'C') |
使い方
import cv2 import numpy as np # NumPyに"np"という省略名をつける # 画像のサイズを指定 width = 200 # 幅 height = 100 # 高さ # RGBの画像として作成して、画素の全てを任意の値で埋める([128, 128, 128]で塗りつぶす)。データ型は符号なし8ビット整数を指定。 color_image = np.full((height, width, 3), 128, np.uint8)
初期化の後に塗りつぶす
画像を初期化した後に塗りつぶしたい場合や既にある画像を塗りつぶしたい場合は、OpenCVの関数を用いる方法があります。
cv2.rectangle関数
rectangle
関数を用いて全体を塗りつぶします。rectangle
関数は塗りつぶしだけでなく、矩形の枠線を描画することもできます。
引数
名称 | 説明 |
入力画像(必須) | 入力画像 |
pt1(必須) | 矩形の頂点座標 |
pt2(必須) | pt1の対角にある矩形の頂点 |
color(必須) | 色 |
thickness(オプション) | ラインの太さ。'-1'を指定すると塗りつぶしになります。 |
lineType(オプション) | 線の種類(デフォルト:cv.2LINE_8 ) |
shift(オプション) | 整数で指定され、座標は"2^shift"割った値となる |
使い方
import cv2 # 画像の大きさを取得 h:高さ、w:幅、channels:チャンネル数 h, w, channels = color_image.shape[:3] # 緑色を作成 green = (0, 255, 0) # cv2 cv2.rectangle(color_image, (0,0), (w-1,h-1), green, thickness=-1) cv2.imwrite('images/init_green.jpg', color_image)
ポイント
完全に画像を塗りつぶすために、画像の画角いっぱいに矩形の塗りつぶしをする必要があります。pt1とpt2にはそれぞれ対角の関係にある画像の角の座標を設定します。
使い方のコードではpt1に左上の(0,0)を設定します。pt2には4行目で取得した画像の大きさを設定しますが、0から始まっているので幅、高さの値からそれぞれマイナス1した値を設定します。
cv2.fillPoly関数
fillPoly
関数を用いて全体を塗りつぶします。この関数は、ポリゴンの内部を指定の色で塗りつぶすことができます。rectangle
関数と同様に、ポリゴンの枠線を描画することもできます。
引数
名称 | 説明 |
入力画像(必須) | 入力画像 |
pts(必須) | 塗りつぶすポリゴンの頂点座標 |
color(必須) | 色 |
lineType(オプション) | 線の種類(デフォルト:cv.2LINE_8 ) |
shift(オプション) | 整数で指定され、座標は"2^shift"割った値となる |
offset(オプション) | ポリゴンの各頂点に対して、x軸方向とy軸方向を個別に指定するのオフセット値 |
offset
引数は、ポリゴンの各頂点に対して、x軸方向とy軸方向のオフセット値を個別に指定する引数です。具体的には、numpy
配列の形式で指定され、各要素は(x, y)
というタプルで、それぞれ頂点のx座標とy座標に対応します。つまり、offset
引数を使用すると、ポリゴンの各頂点の座標を個別に調整することができます。
使い方
import numpy as np import cv2 # 画像を生成する img = np.zeros((200, 200, 3), dtype=np.uint8) # ポリゴンを描画する pts = np.array([[50, 50], [100, 50], [100, 100], [50, 100]], np.int32) pts = pts.reshape((-1,1,2)) cv2.fillPoly(img, [pts], (255, 0, 0)) # ポリゴンをshiftする shifted_img = np.zeros((200, 200, 3), dtype=np.uint8) cv2.fillPoly(shifted_img, [pts], (255, 0, 0), shift=3) # ポリゴンの各頂点を調整する offset_img = np.zeros((200, 200, 3), dtype=np.uint8) offset_pts = np.array([[0, 0], [50, 0], [50, 50], [0, 50]], np.int32) offset_pts = offset_pts.reshape((-1,1,2)) cv2.fillPoly(offset_img, [offset_pts], (0, 255, 0)) # 結果を表示する cv2.imshow("original image", img) cv2.imshow("shifted image", shifted_img) cv2.imshow("offset image", offset_img) cv2.waitKey(0) cv2.destroyAllWindows()
このサンプル コードでは、まずimg
という200x200の黒い画像を生成し、そこにpts
というポリゴンを描画しています。次に、shifted_img
という新しい画像を生成し、shift
引数でshift=3を指定したポリゴンを描画しています。最後に、offset_img
という新しい画像を生成し、offset
引数を使用して各頂点の座標を微調整したポリゴンを描画しています。
おわりに
初期化として使用する最も簡単なものはNumpyをだと思います。cv2.fillPoly関数は初期化としての利用には使いにくいですが、複雑な形状の塗りつぶしに便利な機能になります。
最後までご覧いただきありがとうございました。
■(広告)OpenCVの参考書としてどうぞ!■
参考リンク
OpenCV: Drawing Functions
Draws a simple, thick, or filled up-right rectangle. The function cv::rectangle draws a rectangle outline or a filled rectangle whose two opposite corners are pt1 and pt2.
NumPy: numpy.zeros
Filled with zeros.
NumPy: numpy.full
Filled with fill value.
OpenCV: Drawing Functions
Fills the area bounded by one or more polygons. The function cv::fillPoly fills an area bounded by several polygonal contours. The function can fill complex areas, for example, areas with holes, contours with self-intersections (some of their parts), and so forth.