webカメラの画像を表示して、ボタンを押すと特定のフォルダにjpeg形式で画像を保存するアプリケーションをpythonで作ってみました。
画像処理系のAIの画像データを取得するために作ったアプリケーションです。
コードを公開していますので、ご自由に改造してご利用ください。
pythonの実行環境はすでに用意してある前提で説明します。
用意したもの
今後の改造予定も含め、用意したものは下記の通り
WEBカメラはEMEET SmartCam C960 (画像サイズはFULL HD 1920×1080)
三脚はDAISOにて500円で購入
アプリケーションの実行画面
コードの開示の前に実際のアプリケーションの実行画面はこちら。
いたってシンプルな画面で、アプリケーションを実行したらwebカメラから画像を取得してリアルタイムで表示されます。
ウィンドウ下側中央の「画像保存」ボタンを押すと、特定のフォルダにファイル名が現在時刻のjpegファイルが保存されます。
保存が実行されたら、ボタンの上に保存した画像のファイル名が表示されます。
プログラム動作に必要なモジュールのPIPインストール
今回のプログラムではOpenCVを使用します。
画像処理に必要なモジュールも追加でPIPインストールする必要があります。
pip install opencv-python
pip install Pillow
上記コードをコマンドプロンプトやパワーシェル上で実行してインストールしてください。
アプリケーションのコード
アプリケーションのコードはこちらです。
プログラム中のout-fol変数には画像を保存したいフォルダのパスを入力してください。
cap = cv2.VideoCapture(0)の引数はpcに接続されているカメラの番号を入力する必要がありますので、ご自分のpcの設定に合わせて変更ください。
今回は私の使用しているwebカメラの画素数FULL HD 1920×1080に合わせたウィンドウサイズやcanvasサイズにしていますので、カメラの仕様が違う場合には変更してご利用ください。
import sys
import cv2
import os
import datetime
import tkinter as tk
from PIL import Image, ImageTk
import numpy as np
outfol = 'C:/' #ここに画像を出力保存したいフォルダパスを記述してください
def imwrite(filename, img, params=None):
try:
ext = os.path.splitext(filename)[1]
result, n = cv2.imencode(ext, img, params)
if result:
with open(filename, mode='w+b') as f:
n.tofile(f)
return True
else:
return False
except Exception as e:
print(e)
return False
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.master.title(u"撮影")
self.master.geometry("960x640") # ウィンドウサイズ X1920/2 Y1080/2+100
self.master.resizable(width=False, height=False)
self.canvas = tk.Canvas(master, width=960, height=540, bg="white") # キャンバスサイズをHDの半分に設定
self.canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
# ラベルの初期化
self.label1_text = tk.StringVar()
self.label1_text.set("") # 初期値を空に設定
# ラベルを作成
self.label1 = tk.Label(self.master, textvariable=self.label1_text)
self.label1.pack(side=tk.TOP)
self.capStart()
self.create_widgets()
def update(self):
global p_img
global p_frame
global p_org
ret, p_frame = cap.read()
if ret:
# ウェブカメラから取得したフレームをHDサイズの半分にリサイズ
p_org=p_frame
p_frame = cv2.resize(p_frame, (960, 540))
p_img = ImageTk.PhotoImage(Image.fromarray(cv2.cvtColor(p_frame, cv2.COLOR_BGR2RGB)))
self.canvas.create_image(960 // 2, 540 // 2, image=p_img)
else:
print("u-Fail")
self.label1_text.set("カメラからの映像取得に失敗しました")
self.master.after(50, self.update)
def button1_clicked(self, event):
strtime = '{0:%Y%m%d%H%M%S}'.format(datetime.datetime.now())
imwrite(outfol + '/' + strtime + '.jpg', p_org)
self.label1_text.set("画像を保存しました: " + strtime + ".jpg")
def create_widgets(self):
button1 = tk.Button(self.master, text=str(u"画像保存"))
button1.bind("<1>", self.button1_clicked)
button1.pack(side=tk.TOP)
self.update()
def capStart(self):
print('camera-ON')
try:
global cap
# ウェブカメラの解像度を設定
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
except Exception as e:
print("error:", e)
cap.release()
cv2.destroyAllWindows()
def main():
root = tk.Tk()
app = Application(master=root)
app.mainloop()
if __name__ == "__main__":
main()
今後の改造予定
今後はこのアプリケーションを改造して、下記の項目を実現していこうと考えています。
- 画像内のデジタル表示から数値を取得する
- 特定範囲の画像と数値をデータベース化
- 特定の範囲に写っている物体の分類を行うAIの構築
- 分類された物体の標準偏差などの統計データから閾値を決定し良否判定する
アプリケーションの改造ができたら、記事を更新していきます。
このアプリケーション以外にもpythonのコードを公開している記事もありますので、参考にどうぞ!
コメント