プライバシポリシー
下記、「プライバシーポリシー」に関して記載致しましたので、ご一読願います。
当サイトに掲載されている広告について
当サイトでは、第三者配信の広告サービス(Googleアドセンス)
を利用しています。
このような広告配信事業者は、ユーザーの興味に応じた商品やサービスの広告を表示するため、当サイトや他サイトへのアクセスに関する情報 『Cookie』(氏名、住所、メール アドレス、電話番号は含まれません) を使用することがあります。
またGoogleアドセンスに関して、このプロセスの詳細やこのような情報が広告配信事業者に使用されないようにする方法については、こちらをクリックしてください。
当サイトが使用しているアクセス解析ツールについて
当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。
このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。
このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。
この規約に関して、詳しくはこちら、またはこちら をクリックしてください。
免責事項
当サイトで掲載している画像の著作権・肖像権等は各権利所有者に帰属致します。権利を侵害する目的ではございません。記事の内容や掲載画像等に問題がございましたら、各権利所有者様本人が直接メールでご連絡下さい。確認後、対応させて頂きます。
当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。
当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。
当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。
作成したCNNモデルを使用して、リアルタイムでマスクの有無を判定
実行結果
マスクあり
マスクなし
hanamichi-sukusuku.hatenablog.com
このプログラムでは、上記で作成したモデルを使用してリアルタイムのマスクあり、なしの判定を行っていく。
必要な変数の定義とモデル読み込み、dlibのインスタンス生成
cv2.VideoCapture()で動画処理のためにVideoCaptureオブジェクトを生成。内臓カメラからのデータを取得するために引数に0を指定。USBなどで追加のカメラを接続する場合は0から順番に番号が割り当てられる。
while文でカメラから取得した画像データを繰り返し読み込み処理していく
cap.read()でカメラから取得した画像データを取得。
返り値はbool型のオブジェクト(取得できればTrue、できなければFalse),画像データの二つが返されるためif文で変数okがFalseであれば処理を中止するようにしている。
dlibを使用して顔検出を行う。第二引数の1は顔と認識する最小領域を指定している。1は40✖️40を最小領域として指定。
ウィンドウに描画する内容を記述
enumerate(dets)で顔検出した座標データを元に画像に枠とテキストを描画していく。
pprint.pprint()では複数の配列を改行し、見やすくして表示してくれる。
x1~y2にそれぞれの座標を格納。
frame[y1:y2, x1:x2]で顔の部分を切り取る。
入りとったデータをcv2.resize()でモデルが学習できるサイズに変換し、reshape()で三次元の配列に変換することでCNNでのモデルで扱えるようにする。
変換した画像データをmodel.predict()で予測。
argmax()で最も大きな値を持つインデックス番号を取得。
if文でv == 1の時、つまりマスクをしている時、描画する枠の色をグリーン、ボーダーの太さを2、マスクをしていない時、枠の色を赤、ボーダーの太さを7にするための変数を定義している。
cv2.rectangle()で顔検出した座標に枠を描画。
cv2.putText()でテキストを描画。引数には9個の引数を指定することができる。
第一引数から
- cv2.imread()で読み込んだ画像データ
- 書き込む文字列
- 書き込む位置(文字列の左下の角が指定の位置に配置される。
- フォントスタイル(今回はcv2.FONT_HERSHEY_SIMPLEXを指定している。
- フォントサイズ
- フォントの色
- フォントの太さ
- ラインタイプ
第三引数の位置の指定ではy1から-7を引くことで枠の大きさより上にテキストを表示できる。
画像の保存
len(dets) > 0はつまり顔検出できた配列が存在する時に以下の処理を実行するようにしている。
cv2.imwrite()で任意のファイルに画像データを保存。
ウィンドウに表示
cv2.imshow()でウィンドウを表示し、描画した画像を表示する。第一引数はウィンドウの名前なので任意のもの。
任意のキーが入力された時、処理を中断する
cv2.waitKey()でキーボードからの入力を処理する。引数は指定した数値ミリ秒の間入力を受け付けるというもの。
escは27、enterキーは13となるのでescとenterキーが押されると処理を中断するようにしている。
カメラを閉じ、開いているウィンドウを全て閉じる
作成したCNNモデルを使用して、リアルタイムでマスクの有無を判定
実行結果
マスクあり
マスクなし
hanamichi-sukusuku.hatenablog.com
このプログラムでは、上記で作成したモデルを使用してリアルタイムのマスクあり、なしの判定を行っていく。
必要な変数の定義とモデル読み込み、dlibのインスタンス生成
cv2.VideoCapture()で動画処理のためにVideoCaptureオブジェクトを生成。内臓カメラからのデータを取得するために引数に0を指定。USBなどで追加のカメラを接続する場合は0から順番に番号が割り当てられる。
while文でカメラから取得した画像データを繰り返し読み込み処理していく
cap.read()でカメラから取得した画像データを取得。
返り値はbool型のオブジェクト(取得できればTrue、できなければFalse),画像データの二つが返されるためif文で変数okがFalseであれば処理を中止するようにしている。
dlibを使用して顔検出を行う。第二引数の1は顔と認識する最小領域を指定している。1は40✖️40を最小領域として指定。
ウィンドウに描画する内容を記述
enumerate(dets)で顔検出した座標データを元に画像に枠とテキストを描画していく。
pprint.pprint()では複数の配列を改行し、見やすくして表示してくれる。
x1~y2にそれぞれの座標を格納。
frame[y1:y2, x1:x2]で顔の部分を切り取る。
入りとったデータをcv2.resize()でモデルが学習できるサイズに変換し、reshape()で三次元の配列に変換することでCNNでのモデルで扱えるようにする。
変換した画像データをmodel.predict()で予測。
argmax()で最も大きな値を持つインデックス番号を取得。
if文でv == 1の時、つまりマスクをしている時、描画する枠の色をグリーン、ボーダーの太さを2、マスクをしていない時、枠の色を赤、ボーダーの太さを7にするための変数を定義している。
cv2.rectangle()で顔検出した座標に枠を描画。
cv2.putText()でテキストを描画。引数には9個の引数を指定することができる。
第一引数から
- cv2.imread()で読み込んだ画像データ
- 書き込む文字列
- 書き込む位置(文字列の左下の角が指定の位置に配置される。
- フォントスタイル(今回はcv2.FONT_HERSHEY_SIMPLEXを指定している。
- フォントサイズ
- フォントの色
- フォントの太さ
- ラインタイプ
第三引数の位置の指定ではy1から-7を引くことで枠の大きさより上にテキストを表示できる。
画像の保存
len(dets) > 0はつまり顔検出できた配列が存在する時に以下の処理を実行するようにしている。
cv2.imwrite()で任意のファイルに画像データを保存。
ウィンドウに表示
cv2.imshow()でウィンドウを表示し、描画した画像を表示する。第一引数はウィンドウの名前なので任意のもの。
任意のキーが入力された時、処理を中断する
cv2.waitKey()でキーボードからの入力を処理する。引数は指定した数値ミリ秒の間入力を受け付けるというもの。
escは27、enterキーは13となるのでescとenterキーが押されると処理を中断するようにしている。
カメラを閉じ、開いているウィンドウを全て閉じる
CNNでマスクつけてるかどうかの画像判定
実行結果
このプログラムではCNNモデルを使用してマスクをつけている画像かそうでない画像かの判定を行う。
画像形式の指定
in_shapeは入力値。
nd_classは出力値。
モデル構築
畳み込み、畳み込み、プーリング、ドロップアウトを2回繰り返し、平滑化、全結合層、ドロップアウト、出力層、という流れでCNNモデルの定義し、コンパイルする。
read_files()関数を呼び出し、学習用、テスト用のデータに変換
テスト用の画像データをread_filesで処理する際、x,y = [,]と定義し直しているのは中身を空にするため。
それぞれ最後にnumpy形式に変換し学習用、テスト用の変数に格納。
read_files()関数、画像データとラベルデータに分割し新たな配列を作成
引数に画像データが格納されているパスとラベルデータを渡す。
opencvでデータを読み込んで、画像データ、ラベルデータを空のリストに追加していく。
学習
テストデータを評価しモデルの保存
学習の様子を描画
Dlibを使用して顔検出 python
実行結果
captureディレクトリの画像データから顔検出して、faceディレクトリに検出した顔画像データを保存している。
DlibとはC++言語で書かれた汎用目的のクロスプラットフォームのライブラリで機械学習、画像処理、データマイニングなど幅広い分野の処理が可能。今回は顔検出に利用するが、opencvを用いた方法よりも誤検出が少ないのが特徴。
Dlibの顔検出に使用するインスタンス生成
get_frontal_face_detector()を実行することでインスタンスを生成できる。
captureディレクトリに用意した画像ファイル名を全て取得し、顔検出を行う
get_face()関数に画像ファイル名を渡すことで、その画像から顔検出を行う。
get_face()関数、dlibのインスタンスを利用して顔検出を実行
golbal fidで保存するファイル名の変数をグローバル変数にする。今回は1000を定義しているので処理を行うごとにファイル名が1増えていく。
cv2.imread()で画像データ読み込み。
if flag_resize: では扱う画像データがデジカメなどの大きいものを使用する場合サイズをリサイズするための記述。今回はflag_resizeにFalseを定義しているので実行されない。
detector(img, 1)ではdlibのインスタンスを利用して顔の輪郭の座標を取得している。第一引数には顔検出する画像データ、第二引数には検出する最小領域のパラメーターを指定。デフォルトは0で、この場合80✖️80を最小領域として検出を行う。1の場合は40✖️40、2の場合は20✖️20となる。
pprint.pprintを使用すると、要素ごとに改行して見やすく表示してくれる。
dlibのインスタンスを利用して取得した座標データ(dets)の要素には左端からの座標、一番上からの座標、右側の座標、一番下からの座標が格納されており、left()、top()...とすることでそれぞれの値を取得できる。
img[y1:y2, x1:x2]それぞれ検出した顔の座標を元の画像から切り抜く。
try~except文でtryに例外が起きるかもしれないが実行したい処理、exceptに例外時の処理を記述。tryでは画像を50✖️50の画像データに変換している。exceptではcontinueで処理を飛ばしている。
最後にcv2.imwrite()が検出した画像データを保存し、次のファイル名に使用する変数fidの値を1加えて終了。
オリジナルの写真を作成したCNNモデルで判定
実行結果
上手く出力できた。
プログラムを見ていく。
必要な変数の定義
im_rows、im_clos、im_colorには使用する画像の情報を定義。
in_shapeには入力層で使用する入力を定義。
今回使用するラベルデータは0,1,2の順番で寿司、サラダ、麻婆豆腐なのでLABELSにはその順番になる様に定義。
保存したCNNモデルの読み込み
hanamichi-sukusuku.hatenablog.com
cnn_modelは上記リンクで作成したCNNのモデルを構築するための関数を使用するために冒頭でインポートしている。cnn_model.pyのget_model()関数に入力値、出力値を引数に渡すことでCNNモデルを返り値として受け取ることができる。
hanamichi-sukusuku.hatenablog.com
model.load_weightsで上記で作成した重みデータを取得。
テストしたい画像で関数の実行
check_photo_str()関数
この関数ではcheck_photo()関数に画像のパスを渡して返り値として最も確率の高いラベルデータ(idx)とその確率(per)を取得して、モデルの予測結果がどの料理を指しているのかとカロリー数、確率を出力している。
check_photo()関数、テスト画像を予測し、呼び出し元に結果を返す
Image.open()でPillowを使用して画像を読み込む。
生成したImgaeオブジェクトをconvertで色空間変換。
resize()でサイズ変更。
plt.imshow()でプロットに描画、plt.show()で表示。
モデルで使用できる様に、画像データをnumpy形式に変換、三次元配列に変換、255で割ることで0.0~1.0で表現できる様に変換。
model.predict()で変換したデータの結果を予測。
argmax()で予測結果から最も値の大きいインデックス番号を出力。
int()では引数に渡した値を整数に変換して出力する。