2022年5月1日日曜日

PySimpleGUIとOpenCVでwebカメラ画像中の円を検出する

OpenCVで画像中の円を検出するには、以下のサンプルプログラムのようにHoughCircles関数を使用します。

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

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

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


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)
# イベントループ
while True:
  event, values = window.read(timeout=50)
  if event == sg.WIN_CLOSED:
    break
  rv, frame = capture.read()
  if rv is True:
    # 左右に並べるために縦横のサイズを半分にリサイズ
    resized = cv2.resize(frame, (width, height))
    # グレースケールに変換
    gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
    # HoughCirclesで円を検出
    circles = cv2.HoughCircles(
      gray, cv2.HOUGH_GRADIENT, # methodはHOUGH_GRADIENTまたはHOUGH_GRADIENT_ALT
      dp=1.0, # アキュムレーターは入力イメージと同じ解像度
      minDist=50,  # 検出された円間の最小距離
      param1=110, param2=80 # 検出方式特有のパラメータ。 param1=Canneyエッジ抽出器に渡す高い方の閾値/param2=検出ステージの円中心のアキュムレーター閾値
    )
    # 円を描画
    ci = resized.copy()
    if circles is not None:
      for idx in range(len(circles[0])):
        circle = circles[0][idx]
        ci = cv2.circle(ci, (int(circle[0]), int(circle[1])), int(circle[2]), (0, 192, 0), 2)

    # pngに変換して、Image更新
    img = cv2.imencode('.png', resized)[1].tobytes()
    img2 = cv2.imencode('.png', ci)[1].tobytes()
    window['img1'].update(data=img)
    window['img2'].update(data=img2)


capture.release()
window.close()

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

関連情報

PySimpleGUIで画像を表示する

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

0 件のコメント:

コメントを投稿