2022年4月29日金曜日

PySimpleGUIとOpenCVでwebカメラ画像上に不透明・半透明の楕円を描画する

OpenCVで楕円を描画するにはellipse関数を使用します。thicknessパラメータにcv2.FILLEDを指定すると塗りつぶしになります。
楕円はboxパラメータに((楕円の中心X座標, 楕円の中心Y座標), (幅, 高さ), 角度)というタプルで指定します。
半透明の円を描画するには、描画先の画像を複製して片方にのみ楕円を描画してcv2.addWeighted関数でalpha/betaパラメータを指定して重ね合わせます。

サンプルコードの実行手順

1. PySimpleGUIとOpenCVがインストールされた環境の構築
以下のページを参照して、環境を構築します。
PySimpleGUIとOpenCVをインストールしてwebカメラの映像をウインドウを表示する

2. サンプルプログラムの作成と実行
以下のファイルを保存して、実行します。
psgui_opencv_ellipse.py
import PySimpleGUI as sg
import cv2
import numpy as np

sg.theme('SystemDefault')
layout = [
  [sg.Image(key='img1'), sg.Image(key='img2')]
]

# webカメラをキャプチャー
capture = cv2.VideoCapture(0)

# webカメラの解像度を取得
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)/2)
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)/2)
window = sg.Window("webカメラ画面", layout=layout, finalize=True)
ac = 0
# イベントループ
while True:
  event, values = window.read(timeout=50)
  if event == sg.WIN_CLOSED:
    break
  ac = ac+1
  rv, frame = capture.read()
  if rv is True:
    # 左右に並べるために縦横のサイズを半分にリサイズ
    resized = cv2.resize(frame, (width, height))
    # 半透明描画用に複製
    semitr1 = resized.copy()
    semitr2 = resized.copy()
    # 不透明の楕円を描画
    dx = int(width/10)
    dy = int(height/10)
    cv2.ellipse(resized, ((dx*3, dy*5), (dx*5, dy*4), int(np.mod(30+ac, 360))), (255, 0, 0), 6)
    cv2.ellipse(resized, ((dx*7, dy*5), (dx*5, dy*4), int(np.mod(90+ac, 360))), (255, 0, 0), cv2.FILLED)
    # 半透明の楕円を描画
    cv2.ellipse(semitr2, ((dx*3, dy*5), (dx*5, dy*4), int(np.mod(30+ac, 360))), (255, 0, 0), 6)
    cv2.ellipse(semitr2, ((dx*7, dy*5), (dx*5, dy*4), int(np.mod(90+ac, 360))), (255, 0, 0), cv2.FILLED)
    alpha=0.5
    semitr = cv2.addWeighted(semitr2, alpha, semitr1, 1-alpha, 0)
    # pngに変換して、Image更新
    img = cv2.imencode('.png', resized)[1].tobytes()
    img2 = cv2.imencode('.png', semitr)[1].tobytes()
    window['img1'].update(data=img)
    window['img2'].update(data=img2)


capture.release()
window.close()

・実行方法
以下のコマンドを実行します。
python3 psgui_opencv_ellipse.py

関連情報

PySimpleGUIで画像を表示する

・OpenCVに関する他の記事はこちらを参照してください。

0 件のコメント:

コメントを投稿