ITや趣味など気軽に投稿しています。

【Python】OpenCVで画像に図形を描画する

画像処理では、画像上に図形を描画する場面が多くあります。例えば、物体検知の結果を四角形で囲んで表示したり、注目エリアを円で示したりするケースです。

この記事では、OpenCVを使って画像に線・円・長方形・楕円を描画する方法を解説します。

事前準備

図形を描画する前に、画像の読込とリサイズを行います。

import cv2

path = "input/fox.jpg"
img = cv2.imread(path)
height, width = img.shape[:2]
# 画像のリサイズ(1/4に)
img = cv2.resize(img, (round(width / 4), round(height / 4)))

共通の引数

OpenCVの図形描画関数には、共通の引数がいくつかあります。

座標(pt1, pt2, center)

座標は(x, y)の形式で指定します。単位はピクセルで、画像の左上が原点です。

OpenCV の座標体系

色(color)

カラー画像の場合、色はBGR(Blue, Green, Red)形式で指定します。例えば、黒は(0, 0, 0)、白は(255, 255, 255)です。

線の太さ・塗りつぶし(thickness)

thicknessは線の太さをピクセル単位で指定します。長方形や円の場合、thickness=-1を指定すると図形が塗りつぶしになります。

線の種類(lineType)

アルゴリズム説明
cv2.LINE_44連結
cv2.LINE_88連結(デフォルト)
cv2.LINE_AAアンチエイリアス

LINE_4 < LINE_8 < LINE_AAの順に滑らかな線が描画されます。LINE_AAは最も滑らかですが、描画処理のコストも高くなります。

座標の小数部分のビット数(shift)

shiftは座標の小数部分のビット数を整数で指定するパラメータです(デフォルトは0)。通常は座標を整数で扱いますが、ピクセルより細かい精度で座標を指定したい場合に使用します。shiftを使用する場合は、lineTypecv2.LINE_AAにする必要があります。

線を描く(cv2.line())

直線の描画にはcv2.line()を使用します。

cv2.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
imageLine = img.copy()
# 始点と終点
pt1 = (200, 80)
pt2 = (450, 80)
cv2.line(imageLine, pt1, pt2, (255, 255, 0), thickness=3)
cv2.imshow('Image Line', imageLine)
cv2.waitKey(0)
cv2.line() 実行結果

座標pt1からpt2までの直線が描画されます。色はBGR形式で指定し、上記の例では水色(B=255, G=255, R=0)の線が引かれています。

円を描く(cv2.circle())

円の描画にはcv2.circle()を使用します。

cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]])
引数説明
center円の中心座標
radius円の半径(ピクセル)
imageCircle = img.copy()
circle_center = (350, 280)
radius = 100
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA)
cv2.imshow("Image Circle", imageCircle)
cv2.waitKey(0)
cv2.circle() 実行結果

塗りつぶしの円

thickness=-1を指定すると、円が塗りつぶされます。

cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=-1, lineType=cv2.LINE_AA)
塗りつぶし円

長方形を描く(cv2.rectangle())

長方形の描画にはcv2.rectangle()を使用します。

cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])

pt1は長方形の左上(top-left)、pt2は右下(bottom-right)の座標を指定します。対角の2点を指定することで長方形の形が決まります。

imageRectangle = img.copy()
start_point = (250, 185)
end_point = (430, 385)
cv2.rectangle(imageRectangle, start_point, end_point, (0, 0, 255), thickness=3, lineType=cv2.LINE_8)
cv2.imshow('imageRectangle', imageRectangle)
cv2.waitKey(0)
cv2.rectangle() 実行結果
座標の指定方法

長方形もthickness=-1で塗りつぶしが可能です。

cv2.rectangle(imageRectangle, start_point, end_point, (0, 0, 255), thickness=-1, lineType=cv2.LINE_8)
塗りつぶし長方形

楕円を描く(cv2.ellipse())

楕円の描画にはcv2.ellipse()を使用します。

cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]])
imageEllipse = img.copy()
ellipse_center = (350, 280)
axis1 = (100, 50)
cv2.ellipse(imageEllipse, ellipse_center, axis1, 0, 0, 360, (255, 0, 0), thickness=3)
cv2.imshow('ellipse Image', imageEllipse)
cv2.waitKey(0)
cv2.ellipse() 実行結果

引数

引数説明
center楕円の中心座標
axes(x軸方向の半径, y軸方向の半径)
angle楕円全体の回転角度
startAngle描画開始角度
endAngle描画終了角度

axes: (100, 50)の場合、x軸方向の方が長いため横長の楕円になります。両方を同じ値にすると正円になります。

angle: 楕円全体を回転させる角度です。例えば90°を指定すると、横長の楕円が縦長になります。

startAngle / endAngle: 描画する角度の範囲です。0〜360で全円、0〜180で半円を描画できます。

まとめ

今回は、OpenCVで画像に図形を描画する方法を紹介しました。

  • 直線: cv2.line() で2点間の直線を描画
  • : cv2.circle() で中心と半径を指定して描画
  • 長方形: cv2.rectangle() で対角の2点を指定して描画
  • 楕円: cv2.ellipse() で軸の長さや角度を柔軟に指定
  • thickness=-1塗りつぶしが可能