lisz-works

プログラミングと興味を貴方に

Python3 OpenCVで図形描画!

【スポンサーリンク】

Python

こんにちわ、lisです!

今回はPython3でOpenCVを使った図形の描画です!

図形を描画する関数

基本的な図形として

  1. 矩形
  2. 楕円
  3. 多角形
  4. テキスト

の使い方について書いていきます!

コードは

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()

参考

コチラを参考にしました。ありがとうございました!

labs.eecs.tottori-u.ac.jp

opencv.jp

あとがき

Python3でOpenCVを使った、図形の描画についてでした!

なんだか昔、簡単なおえかきアプリをJavaで作ったのを思い出す内容でした(笑)

www.lisz-works.com

*1:-1, 1, 2