前提
qiitaの記事
「scikit-learnとPC内蔵カメラで、機械学習を用いたリアルタイム顔認識をしてみた」
https://qiita.com/daiarg/items/3ea91b08f0d1cb5bfc61
をトライしてます。
実現したいこと
STEP1. PC内蔵カメラを使って顔写真の収集を行いたいです。
発生している問題・エラーメッセージ
エラーは無く顔認証は行っていますが
ファイル出力されず
jpgファイルにするcv2.imwrite(jpg_n, roi)が上手く行われてない模様です。
※print(jpg_n)は表示されます。
該当のソースコード
import cv2 import glob import time import sys from datetime import datetime cap=cv2.VideoCapture(0) #0にするとmacbookのカメラ、1にすると外付けのUSBカメラにできる # 顔判定で使うxmlファイルを指定する。(opencvのpathを指定) cascade = cv2.CascadeClassifier('C:\\cv2\\data\\haarcascade_frontalface_alt.xml') dir = "C:\\face\\img\\" # 写真を格納するフォルダを指定 num=300 # 欲しいファイルの数 label = str(input("人を判別するを半角英数3文字でで入力してください ex.slf:")) file_number = len(glob.glob("\C:\\face\\img\\/*")) #現在のフォルダ内のファイル数 count = 0 #撮影した写真枚数の初期値 #ラベルの文字数を確認 if not len(label) == 3: print("半角英数3文字で入力してください") sys.exit() while True: #フォルダの中に保存された写真の枚数がnum以下の場合は撮影を続ける if count < num: time.sleep(0.01) #cap reflesh print("あと{}枚です".format(num-count)) now = datetime.now()#撮影時間 r, img = cap.read() # 結果を保存するための変数を用意しておく img_result = img # グレースケールに変換 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #顔判定 minSize で顔判定する際の最小の四角の大きさを指定できる。(小さい値を指定し過ぎると顔っぽい小さなシミのような部分も判定されてしまう。) faces=cascade.detectMultiScale(img_gray, scaleFactor=1.1, minNeighbors=1, minSize=(100, 100)) # 顔があった場合 if len(faces) > 0: # 複数の顔があった場合、1つずつ四角で囲っていく #print("face") for face in faces: #faceには(四角の左上のx座標, 四角の左上のy座標, 四角の横の長さ, 四角の縦の長さ) が格納されている。 #顔だけ切り出して保存 x=face[0] y=face[1] width=face[2] height=face[3] #50×50の大きさにリサイズ roi = cv2.resize(img[y:y + height, x:x + width],(50,50),interpolation=cv2.INTER_LINEAR) jpg_n=dir+label+"__"+str(now)+'.jpg' cv2.imwrite(jpg_n, roi) print(jpg_n) else: print("not") #現在の写真枚数から初期値を減産して、今回撮影した写真の枚数をカウント count = len(glob.glob("/C:\\face\\img/*")) - file_number #フォルダの中に保存された写真の枚数がnumを満たしたので撮影を終える else: break #カメラをOFFにする cap.release()
試したこと
元のプログラムではファイル名の中にドットがつくようになってたので
ドットをつかないファイル名になるように変えてみました
for face in faces: #faceには(四角の左上のx座標, 四角の左上のy座標, 四角の横の長さ, 四角の縦の長さ) が格納されている。 #顔だけ切り出して保存 x=face[0] y=face[1] width=face[2] height=face[3] #50×50の大きさにリサイズ roi = cv2.resize(img[y:y + height, x:x + width],(50,50),interpolation=cv2.INTER_LINEAR) date_n= round(dt_now.microsecond/10000) if date_n<10: date_n="0"+str(date_n) dt_now=str(dt_now.strftime('%Y%m%d_%H:%M:%S'))+str(date_n) jpg_n=dir+label+"__"+str(dt_now)+'.jpg' cv2.imwrite(jpg_n, roi)
*現象かわらずです。
補足情報(FW/ツールのバージョンなど)
OS:Windows10
OpenCV:4.6.0
何がどううまくいっていないのかを具体的に記載ください。
(〇〇エラーが出る、ファイルができない、ファイルが開けないなど)
ありがとうございます。
エラーは出ませんがファイルができないです

> エラーは出ませんがファイルができないです
OpenCVでエラーが出ず画像が保存できていないで一番多いのは「パスがおかしい」です。
print(os.path.split(jpg_n)[0])で表示されるパスが実在のフォルダかどうか確認してください。
※適当にimport osもしてください
OpenCVで画像を保存するときに、保存先に無いフォルダを指定するとエラーがないまま画像が保存されない――ということがおきます。
>print(os.path.split(jpg_n)[0])
を実行すると
C:/face/img
が表示されます。
jpg_n=dir+label+"__"+str(now)+'.jpg'
とされていますが、str(now) にコロンが含まれることになります。Windows ではファイル名にコロン(:)を使用することができません。(reserved character)
Naming Conventions
https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
無事保存され問題解決しました。
ご指摘通り:コロンをファイル名に使ってるのが原因でした。
ありがとうございました。

回答1件
あなたの回答
tips
プレビュー