PythonでUSBカメラのスナップショットを大量に取得する!
USBカメラから自動で大量に画像を取得するプログラムを作った。
用途
機械学習用に大量に画像データを取得するときなど。
プログラムの概要
- 実行すると、フォルダダイアログが立ち上がるので保存先を指定する。保存先に自動的に新規フォルダが作成される。名前にその時の時刻が含まれる。
- そのまま指定した枚数の撮像&保存が始まる。
- 枚数の指定は以下の"10"の部分。上限を1000にしてある。
acquire_save(10, specify_destination())
- While文の中のSleepを調整することで、撮像の間隔を変えられる。
ソースコード
#python 3.8.1 #opencv-contrib-python 4.2.0.32 """ This script acquires and saves a large amount of images from a camera. """ import sys import os from time import sleep from datetime import datetime import tkinter as tk from tkinter import filedialog import cv2 class MyException(Exception): pass def specify_destination(): #Define name of a folder where images will be stored. now = datetime.now() new_folder_name = 'Images_{:%Y%m%d%H%M%S}'.format(now) try: print("Specify a directory to make a new folder to store images.") #Let users specify a directory where a new folder will be made. idir = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\Desktop" dst = filedialog.askdirectory(initialdir = idir) #If users canceled when specifying the directory, raise MyException. if dst == "": raise MyException("Cancel clicked!") #Then, make the folder for storing images. dst_path = os.path.join(dst, new_folder_name) os.mkdir(dst_path) except MyException as e: print(e) sys.exit() except Exception: print("Unexpected error occurred.") sys.exit() else: print("The folder was successfully created.") return dst_path def acquire_save(num_acquisition, save_path): try: #Make a camera instance. cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) #Check if the camera instance is sure to be opened. if not cap.isOpened(): raise MyException("Camera Not Found!") #Check if num_acquisition is integer. if not isinstance(num_acquisition, int): raise MyException("Num of acquisitoin is wrong.") #Check if num_acquisition is less than 1000. if num_acquisition > 1000: raise MyException("Too much number you requested!") #Check if save_path is sure to exist. if not os.path.isdir(save_path): raise MyException("The directory does not exist.") print("Start to acquire and save images repeatedly.") num = num_acquisition while num > 0: print(num) sleep(0.1) _, frame = cap.read() #Define name of images including sequential number. file_name = "sample_{:04}.jpg".format(num) cv2.imwrite(os.path.join(save_path, file_name), frame) num -= 1 except MyException as e: print(e) sys.exit() except Exception: print("Unexpected error occurred.") sys.exit() else: print("Successfully completed!") finally: cv2.destroyAllWindows() cap.release() if __name__ == '__main__': root = tk.Tk() root.withdraw() acquire_save(10, specify_destination())
参考サイト
Pythonで自動化!複数画像から輝度値を取得してテキストに出力する - Python独習!
python - WARN:0 terminating async callback error in cv2 - Stack Overflow
Tkinterのfiledialogでキャンセルするとエラーになる対策 - Qiita
Pythonでディレクトリ(フォルダ)を作成するmkdir, makedirs | note.nkmk.me
OpenCV - カメラで撮影した画像を連番ファイルで保存したい|teratail
ちょっとした気づき
except句にsys.exit()が含まれていても、ちゃんとfinally句は実行されるようだ。