こんにちわ、lisです!
今回はPython3でOpenCVを使った図形の描画です!
図形を描画する関数
基本的な図形として
- 線
- 矩形
- 円
- 楕円
- 多角形
- テキスト
の使い方について書いていきます!
コードは
import cv2 as cv
として書いています。
なお基本的に、thicknessからは指定しなくてもデフォルト引数が設定されています。
なので設定しなくても大丈夫です。
線
def drawLine(img, x1, y1, x2, y2): color = (255, 0, 0) thickness = 3 # 線の太さ cv.line(img, (x1, y1), (x2, y2), color, thickness) drawLine(img, 10, 10, 300, 30)
矩形(四角形)
def drawRectangle(img, x1, y1, x2, y2): color = (0, 255, 0) thickness = 3 # 線の太さ(-1=塗り潰し) return cv.rectangle(img, (x1, y1), (x2, y2), color, thickness) drawRectangle(img, 10, 30, 100, 100)
円
def drawCircle(img, centerX, centerY, radius): color = (0, 0, 255) thickness = -1 # 線の太さ(-1=塗り潰し) cv.circle(img, (centerX, centerY), radius, color, thickness) drawCircle(img, 50, 200, 40)
楕円
def drawEllipse(img, centerX, centerY, axesL, axesS): angle = 0 startAngle = 0 endAngle = 240 color = (0, 255, 0) thickness = -1 # 線の太さ(-1=塗り潰し) cv.ellipse(img, (centerX, centerY), (axesL, axesS), angle, startAngle, endAngle, color, thickness) drawEllipse(img, 200, 180, 100, 50)
多角形
def drawPolylines(img, positions): color = (0, 255, 255) pts = positions.reshape((-1, 1, 2)) cv.polylines(img, [pts], True, color) positions = np.array([[200, 70], [320, 70], [300, 50]], np.int32) drawPolylines(img, positions)
座標の情報は、numpyの配列「np.array()」で作成します。
numpy配列を、polylines()が取り扱う形式にするためにreshape()しています。
reshape()について
positions.reshape*1でやっていることは
array([[200, 170], [320, 170], [300, 200]])
を
array([[[200, 170]], [[320, 170]], [[300, 200]]])
に変換しています。
3次元配列を使うみたいですね。
なのでこれでも動きました。
pts = np.array([[[200, 70], [320, 70], [300, 50]]], np.int32) cv.polylines(img, [pts], True, color)
テキスト
def drawText(img, x, y, text): font = cv.FONT_HERSHEY_SIMPLEX scale = 1 color = (255,255,255) thickness = 2 # 線の太さ lineType = cv.LINE_AA cv.putText(img, text, (x, y), font, scale, color, thickness, lineType) drawPolylines(img, positions)
指定したフォントで描画不可能な文字の場合、「?」となってしまいます。
scale(フォントのスケール)は、フォントの基本サイズにかける係数です。
掛け算なので、単純に
- 0: ほぼ見えなくなる
- 0.5: 少し小さくなる
- 2: 大きくなる
みたいになります。
0はなにか表示されますが、見えないレベルで小さくなるので意味がないです。
色情報
色情報は、BGR形式のint 3つのタプルとなります。
単純に「RGBの逆」です。
以下、簡単な例。
色 | RGB | GBR |
---|---|---|
赤 | 255,0,0 | (0, 0, 255) |
緑 | 0,255,0 | (0, 255, 0) |
青 | 0,0,255 | (255, 0, 0) |
今回試したソース
ソースを開く
import numpy as np import cv2 as cv def drawLine(img, x1, y1, x2, y2): color = (255, 0, 0) thickness = 3 cv.line(img, (x1, y1), (x2, y2), color, thickness) def drawRectangle(img, x1, y1, x2, y2): color = (0, 255, 0) thickness = 3 return cv.rectangle(img, (x1, y1), (x2, y2), color, thickness) def drawCircle(img, centerX, centerY, radius): color = (0, 0, 255) thickness = -1 cv.circle(img, (centerX, centerY), radius, color, thickness) def drawEllipse(img, centerX, centerY, axesL, axesS): angle = 0 startAngle = 0 endAngle = 240 color = (0, 255, 0) thickness = -1 cv.ellipse(img, (centerX, centerY), (axesL, axesS), angle, startAngle, endAngle, color, thickness) def drawPolylines(img, positions): color = (0, 255, 255) pts = positions.reshape((-1, 1, 2)) pts = np.array([[[200, 70], [320, 70], [300, 50]]], np.int32) cv.polylines(img, [pts], True, color) def drawText(img, x, y, text): font = cv.FONT_HERSHEY_SIMPLEX scale = 1 color = (255,255,255) tickness = 2 lineType = cv.LINE_AA cv.putText(img, text, (x, y), font, scale, color, tickness, lineType) def view(img): cv.namedWindow('image', cv.WINDOW_NORMAL) cv.imshow('image', img) def save(path, img): cv.imwrite(path, img) img = np.zeros((512, 512, 3), np.uint8) cv.namedWindow('image') drawLine(img, 10, 10, 300, 30) drawRectangle(img, 10, 30, 100, 100) drawCircle(img, 50, 200, 40) drawEllipse(img, 200, 180, 100, 50) positions = np.array([[200, 70], [320, 70], [300, 50]], np.int32) drawPolylines(img, positions) drawText(img, 10, 300, "text") view(img) key = cv.waitKey(0) & 0xFF if key == 27: # ESC cv.destroyAllWindows() elif key == ord('s'): # s key savePath = './img/output.jpg' save(savePath, img) cv.destroyAllWindows()
参考
コチラを参考にしました。ありがとうございました!
あとがき
Python3でOpenCVを使った、図形の描画についてでした!
なんだか昔、簡単なおえかきアプリをJavaで作ったのを思い出す内容でした(笑)
*1:-1, 1, 2