pysimpleGUIで画像ビューワーの第2弾webカメラの画像を表示して、リアルタイム処理を行う
いままでの記事ではHello medical-python, 画像ビューワーアプリを作成しました。
今回は2つの事を行います
1.pysimpleGUIでWebカメラの画像をリアルタイム表示する
2.2画面ビューワーを作成して2画面目では画像のリアルタイム処理を行う
同じくchatGTPにだいたいの事をやってもらいましょう
chatGPTで迷走したのでBingAIに変更しました
Webカメラのリアルタイム処理(Canny変換)
openCVを使って画像データを表示してきます、GUI処理はpysimpleGUIで行います。
画像はCanny変換して表示します、なぜCanny変換?かっこいいからです。
Canny変換についてBingAIに説明してもらいました。(人任せ、、、)
Canny変換は、画像からエッジを検出するためのアルゴリズムです。エッジとは、画像中の輝度が急激に変化する領域のことを指します。Canny変換は、次のステップで構成されます。
- ノイズ除去: 画像にガウシアンフィルターを適用して、ノイズを除去します。
- 勾配計算: 画像の勾配(輝度の変化量)を計算します。これにより、エッジの方向と強さが求められます。
- 非最大値抑制: 勾配画像中の非最大値を抑制して、細いエッジを得ます。
- ヒステリシスしきい値処理: 2つのしきい値(上限値と下限値)を設定し、勾配強度が上限値より大きいピクセルはエッジとして確定し、下限値より小さいピクセルは非エッジとして除外し、上限値と下限値の間にあるピクセルは、周囲に確定したエッジがある場合にのみエッジとして扱われます。
Canny変換により、画像から輪郭線が抽出されます。このアルゴリズムは、画像処理において広く使用されています。
BingAI
以下指示を与えます
pysimpleGUIを使ってwebカメラの画像をリアルタイム取得し、さらにその画像をcanny処理して表示するコードを教えてください。ただし、canny変換の閾値はスライダーバーで調整できるようにしてください
ちなみにwebカメラのカメラ番号はcap = cv2.VideoCapture(0) の0にしています。複数のカメラがある場合はこの番号を変更します。
import cv2
import PySimpleGUI as sg
# define the window layout
layout = [
[sg.Text("Canny Edge Detection")],
[sg.Image(key="-CANNY-")],
[sg.Text("Threshold 1"), sg.Slider(range=(0, 255), orientation="h", size=(40, 15), default_value=100, key="-THRESHOLD1-")],
[sg.Text("Threshold 2"), sg.Slider(range=(0, 255), orientation="h", size=(40, 15), default_value=200, key="-THRESHOLD2-")],
]
# create the window and show it without the plot
window = sg.Window("Canny Edge Detection", layout)
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0)
while True:
event, values = window.read(timeout=20)
if event == "Exit" or event == sg.WIN_CLOSED:
break
ret, frame = cap.read()
# apply Canny edge detection
edges = cv2.Canny(frame, values["-THRESHOLD1-"], values["-THRESHOLD2-"])
imgbytes = cv2.imencode(".png", edges)[1].tobytes()
window["-CANNY-"].update(data=imgbytes)
window.close()
上記のコードを実行するとこんな感じで動きます。
Webカメラの画像とCanny処理した画像の2画面ビューワーを作る!
上記のコードに追加してwebカメラの生画像を追加します。細かいとこはBingAIに任せます。
pysimpleGUIを使ってwebカメラの画像をリアルタイム表示し、さらにその画像をcanny処理して隣に表示するコードを教えてください。ただし、canny変換の閾値はスライダーバーで調整できるようにしてください。2つの画面は横に並べて表示して下さい。
BingAIの回答は英語が多いです、、
Here is the modified code that displays the webcam feed and its Canny edge detection side by side: 横に並べてってside-by-sideでいいのね
import cv2
import PySimpleGUI as sg
# define the window layout
layout = [
[sg.Text("Canny Edge Detection")],
[sg.Image(key="-IMAGE-"), sg.Image(key="-CANNY-")],
[sg.Text("Threshold 1"), sg.Slider(range=(0, 255), orientation="h", size=(40, 15), default_value=100, key="-THRESHOLD1-")],
[sg.Text("Threshold 2"), sg.Slider(range=(0, 255), orientation="h", size=(40, 15), default_value=200, key="-THRESHOLD2-")],
]
# create the window and show it without the plot
window = sg.Window("Canny Edge Detection", layout)
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0)
while True:
event, values = window.read(timeout=20)
if event == "Exit" or event == sg.WIN_CLOSED:
break
ret, frame = cap.read()
imgbytes = cv2.imencode(".png", frame)[1].tobytes()
window["-IMAGE-"].update(data=imgbytes)
# apply Canny edge detection
edges = cv2.Canny(frame, values["-THRESHOLD1-"], values["-THRESHOLD2-"])
imgbytes = cv2.imencode(".png", edges)[1].tobytes()
window["-CANNY-"].update(data=imgbytes)
window.close()
これで2画面ビューワーができました。
2画面ビューワーに録画機能を付けて動画を保存する
では最後に、このアプリに録画と動画保存機能をつけます。さらに元動画とcanny変換動画を別々に保存しておきます。何故か? 今後の展開を待っててください。
BingAIにいろいろ頼みます。(何回かチャットしたのを端折っています)
上記のコードにstart_recとstop_recのボsave_movieのボタンを追加して、start_recで画面の録画を開始、stop_recで録画を終了、save_movieで録画した動画をmp4で保存するコードをおしえてください。
ただし、mp4のファイル名は現在の時刻としてください。
canny処理した画像も別のmp4に保存するコードを追加してください。
英語でたくさん解説してくれたのですが、日本語に訳してもらいました。
このコードでは、録画の開始と停止、および動画の保存を行うための3つの新しいボタン要素がレイアウトに追加されています。Start Recordingボタンがクリックされると、各フレームがリストに追加され、Webカメラのフィードが記録されます。Stop Recordingボタンがクリックされると、録画が停止します。Save Movieボタンがクリックされると、記録されたフレームがOpenCVのcv2.VideoWriterを使用してMP4ファイルとして保存されます。保存された動画のファイル名は、現在の日付と時刻をYYYY-MM-DD_HH-MM-SS.mp4の形式で設定されます。
このコードは、必要なライブラリ(PySimpleGUIおよびopencv-python)をpip install PySimpleGUI opencv-pythonを使用してインストールした後、コンピューターで実行できます。コードを実行する前に、コンピューターにWebカメラが接続されていることを確認してください。
import cv2
import PySimpleGUI as sg
from datetime import datetime
# define the window layout
layout = [
[sg.Text("Canny Edge Detection")],
[sg.Image(key="-IMAGE-"), sg.Image(key="-CANNY-")],
[sg.Text("Threshold 1"), sg.Slider(range=(0, 255), orientation="h", size=(40, 15), default_value=100, key="-THRESHOLD1-")],
[sg.Text("Threshold 2"), sg.Slider(range=(0, 255), orientation="h", size=(40, 15), default_value=200, key="-THRESHOLD2-")],
[sg.Button("Start Recording", key="-START-"), sg.Button("Stop Recording", key="-STOP-", disabled=True), sg.Button("Save Movie", key="-SAVE-", disabled=True)],
]
# create the window and show it without the plot
window = sg.Window("Canny Edge Detection", layout)
# ---===--- Event LOOP Read and display frames, operate the GUI --- #
cap = cv2.VideoCapture(0)
recording = False
frames = []
canny_frames = []
while True:
event, values = window.read(timeout=20)
if event == "Exit" or event == sg.WIN_CLOSED:
break
ret, frame = cap.read()
imgbytes = cv2.imencode(".png", frame)[1].tobytes()
window["-IMAGE-"].update(data=imgbytes)
# apply Canny edge detection
edges = cv2.Canny(frame, values["-THRESHOLD1-"], values["-THRESHOLD2-"])
imgbytes = cv2.imencode(".png", edges)[1].tobytes()
window["-CANNY-"].update(data=imgbytes)
# handle recording
if recording:
frames.append(frame)
canny_frames.append(edges)
if event == "-START-":
recording = True
window["-START-"].update(disabled=True)
window["-STOP-"].update(disabled=False)
elif event == "-STOP-":
recording = False
window["-START-"].update(disabled=False)
window["-STOP-"].update(disabled=True)
window["-SAVE-"].update(disabled=False)
elif event == "-SAVE-" and frames:
# save frames as MP4 file
height, width, _ = frames[0].shape
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
filename = datetime.now().strftime("%Y-%m-%d_%H-%M-%S.mp4")
out = cv2.VideoWriter(filename, fourcc, 20.0, (width, height))
for frame in frames:
out.write(frame)
out.release()
frames.clear()
# save canny frames as MP4 file
height, width = canny_frames[0].shape
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
filename = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_canny.mp4")
out = cv2.VideoWriter(filename, fourcc, 20.0, (width,height))
for frame in canny_frames:
out.write(cv2.cvtColor(frame,cv2.COLOR_GRAY2BGR))
out.release()
canny_frames.clear()
window["-SAVE-"].update(disabled=True)
window.close()
実行すると現在の作業フォルダにwebカメラの動画と、canny処理後の動画が保存されます。
pysimpleGUIとopenCVを使って、webカメラから動画とcanny変換した動画を保存しました。本日はここまで!
| PythonによるOpenCV4画像処理プログラミング+Webアプリ入門 [ 北山直洋 ] 価格:4,400円(税込、送料無料) (2023/5/12時点)楽天で購入 |


コメント