↓もし、良かったらSNSでの紹介よろしくお願いします。

OpenCV(Python)GUIの基礎、線を描く。

bootstrap

はじめに

OpenCVのGUI基礎編です。前回は画像の表示を解説しました。今回は線の描画について解説します。

準備

img.jpgというファイル名で画像を用意してください。今回は下記の画像を使用して解説します。また、保存した画像と同じディレクトリでスクリプトを実行していきます。

img

線を描く

# -*- coding: utf-8 -*-
import cv2
#sx, syは線の始まりの位置
sx, sy = 0, 0
#マウスの操作があるとき呼ばれる関数
def callback(event, x, y, flags, param):
    global img, sx, sy
    #マウスの左ボタンがクリックされたとき
    if event == cv2.EVENT_LBUTTONDOWN:
        sx, sy = x, y
    #マウスの左ボタンがクリックされていて、マウスが動いたとき
    if flags == cv2.EVENT_FLAG_LBUTTON and event == cv2.EVENT_MOUSEMOVE:
        cv2.line(img, (sx, sy), (x, y), (255, 0, 0), 1)
        sx, sy = x, y
#画像を読み込む
img = cv2.imread("img.jpg")
#ウィンドウの名前を設定
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
#コールバック関数の設定
cv2.setMouseCallback("img", callback)
while(1):
    cv2.imshow("img", img)
    k = cv2.waitKey(1)
    #Escキーを押すと終了
    if k == 27:
        break
    #sを押すと画像を保存
    if k == ord("s"):
        cv2.imwrite("painted.png", img)
        break

cv2.setMouseCallback

#コールバック関数の設定
cv2.setMouseCallback("img", callback)

コールバック関数とはあるイベントがあったとき呼び出される関数のことです。cv2.setMouseCallbackはマウスの操作があったときのコールバック関数を設定します。

コールバック関数の引数

#マウスの操作があるとき呼ばれる関数
def callback(event, x, y, flags, param):
    global img, sx, sy
    #マウスの左ボタンがクリックされたとき
    if event == cv2.EVENT_LBUTTONDOWN:
        sx, sy = x, y
    #マウスの左ボタンがクリックされていて、マウスが動いたとき
    if flags == cv2.EVENT_FLAG_LBUTTON and event == cv2.EVENT_MOUSEMOVE:
        cv2.line(img, (sx, sy), (x, y), (255, 0, 0), 1)
        sx, sy = x, y

コールバック関数の引数は5つです。eventはマウスの操作を表す変数です。xはマウスの横軸の位置、yはマウスの縦軸の位置を表します。flagsはマウスボタンの状態を表します。

paramはcv2.setMouseCallbackに3つ目の引数を入れるとparamで値を受けとることができます。

グローバル変数

    global img, sx, sy

コールバック関数はparamで値を受け取ることができますがglobal変数を用いるのがおすすめです。

関数外の変数へアクセスしたい場合、関数内でglobalを付けて宣言することで、その変数へアクセスできます。

global変数によって、画像imgと線の始点sx, syにコールバック関数がアクセスできるようになります。

コールバック関数の動作

#マウスの左ボタンがクリックされたとき
if event == cv2.EVENT_LBUTTONDOWN:
    sx, sy = x, y

左のボタンがクリックされたときの操作です。このときは、線の始点を決定するだけです。

cv2.EVENT_LBUTTONDOWNはマウスで左クリックが行われた状態を表す定数です。マウスイベントの一覧に関しては後のほうにまとめてます。

#マウスの左ボタンがクリックされていて、マウスが動いたとき
if flags == cv2.EVENT_FLAG_LBUTTON and event == cv2.EVENT_MOUSEMOVE:
    cv2.line(img, (sx, sy), (x, y), (255, 0, 0), 1)
    sx, sy = x, y

そして、左のボタンがクリックされた状態でマウスを動かしたときに、線を描画します。この線はマウスの始点と現在のマウスの位置を結ぶ線です。

さらに、線を描いた後に始点の更新を行います。

cv2.EVENT_FLAG_LBUTTONはマウスの左ボタンが押されている状態を表す定数です。後のほうにマウスフラグの一覧をまとめています。

cv2.EVENT_MOUSEMOVEはマウスが動いたイベントを表します。

cv2.line(img, start_point, end_point, color, thickness)は線を描く関数です。start_pointは始点のx座標とy座標を渡します。end_pointも同じです。colorはBGR形式(青緑赤の値)で線の色を選択します。thicknessで線の太さを設定します。

マウスイベントの一覧(Python)

  • cv2.EVENT_MOUSEMOVE:マウスが移動した
  • cv2.EVENT_LBUTTONDOWN:マウスの左ボタンが押された
  • cv2.EVENT_RBUTTONDOWN:マウスの右ボタンが押された
  • cv2.EVENT_MBUTTONDOWN:マウスの中ボタンが押された
  • cv2.EVENT_LBUTTONUP:マウスの左ボタンを離した
  • cv2.EVENT_RBUTTONUP:マウスの右ボタンを離した
  • cv2.EVENT_MBUTTONUP:マウスの中ボタンを離した
  • cv2.EVENT_LBUTTONDBCLK:マウスの左ボタンがダブルクリックされた
  • cv2.EVENT_RBUTTONDBCLK:マウスの右ボタンがダブルクリックされた
  • cv2.EVENT_MBUTTONDBCLK:マウスの中ボタンがダブルクリックされた

マウスフラグの一覧(Python)

  • cv2.EVENT_FLAG_LBUTTON:マウスの左ボタンがクリックされた状態
  • cv2.EVENT_FLAG_RBUTTON:マウスの右ボタンがクリックされた状態
  • cv2.EVENT_FLAG_MBUTTON:マウスの中ボタンがクリックされた状態
  • cv2.EVENT_FLAG_CTRLKEY:Ctrlキーが押された状態
  • cv2.EVENT_FLAG_SHIFTKEY:Shiftキーが押された状態
  • cv2.EVENT_FLAG_ALTKEY:Altキーが押された状態