Arduino UNO Qの顔認識アプリの顔データ学習要領

Arduino UNO Qで、カメラに映った人の顔を認識して、予め登録した人物の誰であるかを判別するアプリを作りたい場合、顔データの学習をどのように行えばよいかを調べた。まず、作りたいアプリの内容を入力すれば、どのBrickが必要かを回答してくれるGem(名称:Arduino App Lab Architect)を作り、そのGemに質問することから始めた。
調べてみると、Arduino UNO Qに組み込む顔データの作成は結構手間のかかる作業であることが分かった。そのため、本記事も長くなっている。

(注)本記事の内容は正確性を保証するものではない。

(2025年12月22日 追記)YouTube動画を追加しました。 https://youtu.be/RKHaNjLFNXA

目次

必要なBrick調査

カメラに映った人の顔を認識して、誰かを判別するアプリを作りたい

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino UNO App Labの専門コンサルタント、Architectです。

「カメラに映った人の顔を認識して、それが誰であるかを判別(個人特定)するアプリ」を作成したいとのことですね。素晴らしいアイデアです。セキュリティシステムや、個人の好みに合わせた自動化(スマートホーム)など、応用の幅が広い分野です。

ご提示いただいたアイデアを実現するために、現在利用可能な【Bricksリスト】から最適な構成を分析・提案いたします。

1. 分析と構成案

ユーザー様の要件を分解すると、以下の技術要素が必要になります。

  1. 映像取得: カメラからのライブ映像入力。
  2. 物体検出と分類: 映像の中から「顔」を見つけ出し、さらにその顔が「Aさん」か「Bさん」かを分類する。
  3. 結果表示: 判定結果(誰か)や映像をユーザーに表示する。

2. Bricksの照合と提案

この機能を実現するため、以下のBricksを組み合わせることを推奨します。

推奨するBricks

  • video_objectdetection
    • 理由: このBrickは「カメラからのライブ映像フィード内のオブジェクトや顔を分類・検出する」機能を持っています。これがアプリの核となります。
    • 補足: 一般的なモデルでは単に「人の顔 (Face)」として検出されますが、このBrickで使用する機械学習モデルを、「Aさんの顔」「Bさんの顔」というラベルで学習(転移学習など)させることで、誰であるかの判別が可能になります。
  • web_ui
    • 理由: カメラの映像をリアルタイムで確認し、「誰と認識されたか」という結果を表示するためのインターフェースとして必要不可欠です。信頼度(どれくらいの確率でその人か)の表示も可能です。
  • dbstorage_sqlstore (オプション)
    • 理由: 必須ではありませんが、「誰が・いつ」認識されたかというログ(入退室記録など)を残したい場合に、このBrickでイベントデータを保存すると実用性が高まります。

3. 実現における重要な技術的アドバイス

ご提案した video_objectdetection を使用する上で、一つ重要な技術的ハードル(注意点)があります。

「検出」と「識別」の違いについて

リストにある機能は「オブジェクトや顔を分類・検出」するものです。

  • デフォルトの状態: 多くの場合、初期状態のモデルは「これは人間です」「これは顔です」までは分かりますが、「これは田中さんです」とは分かりません。
  • 実現方法: 「誰か」を判別するためには、Arduino UNO R4などのエッジデバイス向けに、判別したい特定の人物の顔写真データを集め、カスタムモデル(Edge Impulseなどを利用)をトレーニングする必要があります。

結論:

現在のBricksリストで実現可能です。ただし、video_objectdetection に組み込むAIモデルの中身(学習データ)を、特定の個人用にカスタマイズする必要がある点をご留意ください。

まずは video_objectdetectionweb_ui を組み合わせて、プロトタイプを作成してみましょうか?

Edge Impulse調査

「Edge Impulseなどを利用」ということですが、Edge Impulseとは何ですか

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

「Edge Impulse(エッジ・インパルス)」についてのご質問ですね。
これは、今回の「特定の誰かを判別する」という機能をArduinoで実現するために、最も重要な「頭脳(AIモデル)」を作るための開発プラットフォームです。

分かりやすく解説します。

Edge Impulse とは?

一言で言うと、「Arduinoのような小さなマイコンでも動くAI(機械学習モデル)を、専門知識がなくてもブラウザ上で簡単に作れるツール」です。

通常、Arduinoのプログラミングは「もしスイッチが押されたら、LEDを光らせる」といったルールを人間が書きます。

しかし、「この顔はAさんか、Bさんか?」という判断をルールで書くのは不可能です。
そこで、AIに大量の画像を見せて学習させる必要があります。この「学習」を担当するのがEdge Impulseです。

なぜ必要なのか?(今回のアプリにおける役割)

先ほど提案したBrick video_objectdetection は、いわば「空のビデオデッキ」のようなものです。
これ単体では、「何か物体がある」ことしか分かりません。

「これは田中さんの顔だ」と理解させるためには、「田中さんの顔を学習したデータ(ビデオテープ)」をセットする必要があります。この「学習済みデータ(AIモデル)」を作成できるのがEdge Impulseです。

具体的な使い方の流れ

今回の「顔判別アプリ」を作る場合、Edge Impulseでは以下のような手順になります。

  1. データの収集 (Data Acquisition):Edge Impulseの画面を通して(またはスマホ経由で)、判別したい人(あなたや友人など)の顔写真をそれぞれ数十枚〜百枚程度撮影してアップロードします。
  2. 学習 (Impulse Design):「画像分類(Transfer Learningなど)」というメニューを選び、「学習開始」ボタンを押します。
    難しい計算はすべてクラウド上のサーバーが行ってくれます。
  3. デプロイ (Deployment):学習が終わると、Arduino用の「ライブラリ」としてファイルをダウンロードできます。
  4. 組み込み:ダウンロードしたライブラリをArduinoに読み込ませることで、先ほどの video_objectdetection Brickが、あなたの顔を認識できるようになります。

Edge Impulseのメリット

  • クラウド不要: 一度学習したモデルをArduino本体(Edge)に入れるため、インターネットに繋がっていなくても、カメラ単体で瞬時に顔判別ができます。
  • 無料枠あり: 開発者向けの無料プランがあり、個人での学習や実験には十分な機能が使えます。
  • Arduino公式提携: Arduinoと非常に相性が良く、連携機能が充実しています。

まとめ

  • Arduino App Lab: アプリの「体」や「機能ブロック」を提供する場所。
  • Edge Impulse: アプリの「脳(誰の顔か見分ける知能)」を作る場所。

この2つを組み合わせることで、高度なAIアプリが完成します。

Edge Impulseを使った「顔認識モデル」の作り方について、もう少し具体的な手順を知りたいですか?
それともBricksの構成について他にご質問はありますか?


Edge Impulseの利用方法を教えてください

Architect(Gemini 3 Pro)の回答

承知いたしました。Arduino App Lab Architectとして、Edge Impulseを使って「特定の人の顔を判別するAIモデル」を作成する具体的な手順を解説します。

プロセスは大きく4つのステップ(データの収集、設計、学習、書き出し)に分かれます。
専門的な知識は不要で、ブラウザ上の操作で完結します。

ステップ1: データの収集 (Data Acquisition)

AIに「誰がAさんで、誰がBさんか」を教えるための写真素材を集める工程です。ここが最も重要です。

  1. プロジェクト作成: Edge Impulseにログインし、「Create new project」をクリックします。
  2. デバイス接続: Arduinoを繋ぐ方法もありますが、スマートフォンを使うのが一番簡単です。「Devices」タブから「Connect a new device」を選び、表示されるQRコードをスマホで読み取ります。
  3. 撮影とラベル付け:
    • スマホがカメラモードになります。
    • Label(ラベル)に名前(例: Tanaka, Suzuki, Background)を入力します。
    • 撮影: 様々な角度、明るさ、距離で、それぞれの顔写真を約50枚〜100枚ずつ撮影します。
    • 重要: Background(誰も映っていない背景だけ)の画像も必ず学習させてください。これがないと、壁を見ても「田中さん」と誤判定してしまいます。

ステップ2: インパルスの設計 (Create Impulse)

収集したデータ(画像)をどのように処理するか、AIの「流れ」を設計します。

  1. Create Impulse画面:
    • Image data: 画像サイズ(例: 96×96など)を設定します。小さいほどArduinoでの処理が速くなります。
    • Processing block: 「Image」を選択します。
    • Learning block:
      • 顔の位置まで特定したい場合: 「Object Detection (Images)」を選びます。
      • 単に画面全体で誰か判断したい場合: 「Transfer Learning (Images)」を選びます。(初心者にはこちらが推奨です)
    • 「Save Impulse」をクリックします。

ステップ3: 学習 (Generate Features & Training)

AIに勉強させる工程です。

  1. 特徴抽出 (Image):
    • 「Generate features」ボタンを押します。画像データが数値化され、AIが理解できる形に変換されます。
  2. トレーニング (Transfer Learning / Object Detection):
    • Neural Network settings: 基本的にデフォルト設定で構いません。
    • Model: Arduino UNO R4などのマイコン向けには、「MobileNetV2」などの軽量なモデルを選択します。
    • 「Start training」をクリックします。
    • 数分後、学習が完了し、正答率(Accuracy)が表示されます。80%〜90%以上出ていれば優秀です。

ステップ4: デプロイ (Deployment)

完成したAIモデルをArduino用のファイルとして書き出します。

  1. Deploymentタブ: 左メニューから「Deployment」を選択します。
  2. Search deployment options: 検索窓に「Arduino」と入力し、「Arduino library」を選択します。
  3. Build: 画面下の「Build」ボタンを押します。
  4. ダウンロード: 数分でビルドが完了し、ZIPファイル(Arduinoライブラリ形式)がダウンロードされます。

アプリへの組み込み方

ここでダウンロードしたZIPファイル(ライブラリ)を、Arduino IDEにインポートします。

  1. Bricksとの連携:先ほど提案した video_objectdetection のBrickは、デフォルトのモデルの代わりに、このEdge Impulseで作成したライブラリを読み込むように設定を変更します。
  2. 動作確認:これで、あなたのArduinoは「一般的な顔」ではなく、「学習させた特定の人物」を見分ける能力を持つようになります。

Architectからのアドバイス

  • 光の加減: 学習させた場所と、実際に使う場所の明るさが大きく違うと認識率が下がります。なるべく本番環境に近い場所でデータを集めるのがコツです。

この手順で進めていけそうですか? もし「スマホでのデータ収集」について詳しく知りたい場合や、次のステップへ進みたい場合はお声がけください。

画像生成AIによる水増しデータの有効性

データ収集ですが、認識したい人の写真を色々な角度から10枚程度撮影し、それらの写真を、通称Nano Banana Proのような画像生成AIに入力して、さらに違う方向からの画像や、笑っている画像や、人を消して背景だけにした画像を量産させ、データ数を50以上にするという方法は使えますか

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

非常に鋭く、現代的なアプローチですね。「Nano Banana Pro」(おそらく画像生成AIツールの一種と推察します)のような生成AIを使ってデータセットを水増し(データ拡張)するというアイデア、技術的には「シンセティックデータ(Synthetic Data)の活用」と呼ばれ、AI開発の最前線でも研究されている手法です。

結論から申し上げますと、「背景画像(人がいない画像)の量産には非常に有効ですが、顔画像の量産には大きなリスクが伴うため、推奨しません」というのが専門的な回答になります。

その理由と、より確実な代替案を解説します。

1. なぜ「顔画像」の生成AI量産はリスクがあるのか?

Edge Impulse等の軽量AIモデルが人の顔を見分けるとき、「目と目の距離」「鼻の高さ」「あごのライン」といった微細な特徴を数値化して判断しています。

  • アイデンティティの揺らぎ:生成AIは「笑っている顔」や「横顔」を作る際、本人の特徴を微妙に補正(美化したり、平均的な顔に寄せたり)してしまう傾向があります。人間が見ると「似ている」と思えても、AIの判定基準からすると「別人」になってしまうことが多々あります。
  • 嘘の特徴(アーティファクト)の学習:生成AI特有のノイズや、不自然な皮膚の質感などをAIが「その人の特徴」として誤って学習してしまうと、現実のカメラ映像(実写)が入ってきたときに認識できなくなります。

2. 「背景画像」の量産には最適です

一方で、アイデアにあった「人を消して背景だけにした画像を量産する」という使い方は非常に素晴らしいです。

  • 誤認識の防止: 顔認識AIにとって、「誰もいない背景」を「誰もいない」と正しく判断させることは非常に重要です。
  • バリエーション: 部屋の照明を変えたバージョンや、家具の配置が変わったバージョンなどを生成AIで作って「Background」クラスに学習させることは、モデルの頑健性を高めるのに役立ちます。

3. Architectからの推奨代替案(最も効率的な方法)

10枚の写真からAIで50枚を作るよりも、もっと簡単で、かつ精度の高い方法があります。

「動画(Video)からの切り出し」です。

Edge Impulse(およびスマホ)を使った収集では、以下の手順がベストプラクティスです。

  1. スマホのカメラを動画モードにします。
  2. その人の顔を映しながら、10秒間、ゆっくり首を回したり、笑ったり、近づいたり離れたりしてもらいます。
  3. 10秒の動画は、例えば30fpsなら300枚の画像に相当します。
  4. Edge Impulseには、動画を自動的に分割して画像データセットにする機能があります。

結論:

  • 顔データ: 生成AIで作るよりも、「10秒の動画」を1本撮るだけで、リアルかつ300枚以上の高品質なデータが手に入ります。こちらを強く推奨します。
  • 背景データ: 撮影が面倒な場合、生成AIでバリエーションを増やすのはアリです。

まずは「スマホで動画を撮って自動分割」という機能を試していただくのが、アプリ完成への一番の近道ですよ。

いかがでしょうか? この「動画からデータを作る」手順で進めてみますか?

人画像と背景画像との混合割合調査

10秒の動画でデータ収集できるなら、その方法を実施したいと思いますが、人が写っている画像と、背景画像とはどのような割合で混ぜればいいとかの目安はありますか

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

「動画切り出し」の手法を選択されたとのこと、賢明な判断です! 手間が圧倒的に少なく、かつ「様々な表情や角度」が自然に含まれるため、AIの精度も上がりやすいです。

ご質問の「人物画像と背景画像の割合(バランス)」について、成功のための黄金比をお伝えします。

1. 推奨する比率: 「均等(1 : 1)」が基本

AIモデルの学習において、データセットのバランスは非常に重要です。

  • 基本ルール: 全てのクラス(分類したい項目)のデータ量をほぼ同じにします。
  • 具体例: もし「Aさん」と「Bさん」と「背景(誰もいない)」を識別したい場合、理想的な比率は 1 : 1 : 1 です。

なぜ均等が良いのか?

もし「Aさんの画像が100枚」で「背景が10枚」しかないと、AIは「とりあえず迷ったらAさんと答えておけば、確率的に正解しやすい」と学習してしまい、壁を映しても「Aさん」と誤判定するようになります(これを過学習と呼びます)。

2. 「背景」データの考え方と収集テクニック

実は、顔認識アプリにおいて最も重要なのは、顔ではなく「背景(Background)」クラスの質です。
ここが弱いと誤作動だらけのアプリになります。

動画でデータを集める際は、以下の構成をおすすめします。

構成案(3クラス分類の場合)

  1. Aさん(Target A): 約300枚(約10〜15秒の動画)
  2. Bさん(Target B): 約300枚(約10〜15秒の動画)
  3. 背景(Background): 約300枚(約10〜15秒の動画)

背景動画の撮り方のコツ

ただ「空っぽの壁」を撮るだけでは不十分です。
AIに「これらは顔ではない」と教える必要があります。
以下の要素を混ぜて1本の動画(または数本の動画)にしてください。

  • 設置場所の風景: アプリを使う予定の部屋の壁、天井、床。
  • 誤認識しやすそうなもの: 人の顔に見えがちなもの(壁のポスター、時計、観葉植物、複雑な模様のカーテンなど)。
  • (応用)知らない人: もし可能なら、「AさんでもBさんでもない人(Cさん)」を「背景(その他)」として学習させると、セキュリティ強度が劇的に上がります。

3. 具体的なアクションプラン

Edge Impulseの「Data acquisition」画面で、以下のように進めてください。

  1. Aさんの撮影:
    • Label: Person_A
    • 動画撮影(10〜15秒):正面、少し横を向く、上を向く、笑顔、真顔などを混ぜながら。
  2. 背景の撮影:
    • Label: Background
    • 動画撮影(10〜15秒):カメラをゆっくり動かしながら、部屋の中の顔以外のあらゆるものを映します。
  3. データの分割(Split):
    • Edge Impulseでデータをアップロードすると、自動的に「Training(学習用:80%)」「Testing(テスト用:20%)」に振り分けてくれることが多いですが、もし聞かれたらこの割合を目安にしてください。

まとめ:

Aさんの動画を1本(15秒)、背景の動画を1本(15秒)。
これだけで、おおよそ 1:1 のバランスの取れたデータセットが完成します。

これでデータの準備に関しては完璧です。撮影を開始してみましょうか?
それとも、次の「学習(Impulse Design)」の設定について先に知っておきたいことはありますか?

「学習」の設定

「学習(Impulse Design)の設定」とは何を行うことかを説明してください

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

「Impulse Design(インパルス・デザイン)」、耳慣れない言葉ですよね。

これは、集めた写真データをAIがどのように料理するかを決める、いわば「AIのレシピ(設計図)」を作る工程です。

Edge Impulseの画面では、ブロックを左から右に並べることで、データの流れ(パイプライン)を設計します。

大きく分けて3つのステップを設定します。それぞれ何を行っているのか、分かりやすく解説します。

1. 入力設定(Input block)

役割:食材を一口サイズにカットする

カメラで撮った写真はデータサイズが大きすぎます(数百万画素など)。小さなマイコンであるArduinoがこれをそのまま処理しようとすると、メモリが溢れてパンクしてしまいます。

  • 何をする設定?
    • Image data: ここで画像をArduinoが扱えるサイズ(例:96 x 96 ピクセル や 160 x 160 ピクセル)にギュッと縮小する設定をします。
    • Resize mode: 画像を正方形にリサイズする際、端を切り落とすか(Crop)、押し潰すか(Squash)を選びます。基本は「Fit shortest axis(短い辺に合わせる)」でOKです。

ポイント: 画質は荒くなりますが、AIは「モザイク画」のような状態でも十分に特徴(目鼻立ちの配置など)を捉えることができます。

2. 特徴抽出(Processing block)

役割:味の染み込みやすい下ごしらえをする

AIはいきなり「顔」を見るわけではありません。画像の「色」や「輝度」のデータから、AIにとって理解しやすいヒント(数値)を取り出します。

  • 何をする設定?
    • Add processing block: ここで「Image」というブロックを選びます。
    • これは、画像を数値の羅列(RGBデータやグレースケール)に変換し、AIが学習できる状態に整える処理です。

3. 学習モデル選択(Learning block)

役割:メインディッシュの調理法(脳みその種類)を決める

ここが一番重要です。どのようなルールで学習するかを選びます。

  • 何をする設定?
    • Add learning block: 以下のどちらかを選びます。
    1. Transfer Learning (Images)【推奨】
      • 「画像分類」です。「この画像全体はAさんですか? Bさんですか?」を判定します。
      • 特徴: 既に賢いAI(学習済みモデル)を、あなたの顔用に少しだけ再教育する方法です。
        少ないデータでも高精度が出やすく、Arduinoでも高速に動きます。
    2. Object Detection (Images)
      • 「物体検出」です。「画像のどこに顔があり、それは誰ですか?」を判定します。
      • 特徴: 顔の位置まで分かりますが、処理が重く、データの作成(顔の部分を四角枠で囲む作業)が大変です。

Architectからの提案:

今回は「誰か判別する」ことが主目的ですので、まずは設定が簡単で精度が出やすい 1. Transfer Learning (Images) を選ぶことを強くおすすめします。

まとめ:この画面でやること

ユーザー様が行う操作は以下の通りです。

  1. 画像のサイズを 96×96 に設定する。
  2. Processing blockに 「Image」 を追加する。
  3. Learning blockに 「Transfer Learning」 を追加する。
  4. 最後に 「Save Impulse」 ボタンを押す。

これが完了すると、左側のメニューに「Image」と「Transfer Learning」という新しい項目が出現し、詳細な調整(実際に学習ボタンを押す画面)に進めるようになります。

この「レシピ作成」、イメージいただけましたでしょうか?

もしよろしければ、設定が終わった後に進む「Generate features(特徴抽出)」の作業についてもご案内できますが、いかがなさいますか?

特徴抽出

Generate features(特徴抽出)の作業について教えてください

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

「Generate features(特徴抽出)」は、専門用語っぽくて難しそうに見えますが、やっていることは非常にシンプルです。

一言で言うと、「画像を、AIが理解できる『数値の指紋』に変換する作業」です。

人間は写真を見て「これはAさんの目だ」と分かりますが、コンピュータにとってはただの色の点の集まりです。
そこで、画像の中から「ここが重要なパターンだ」というエッセンス(特徴)だけを抜き出し、計算しやすい数値データに変換します。

具体的な手順と、この画面で「絶対に確認すべきポイント」を解説します。

1. 手順:ボタンを押すだけ

前のステップで「Save Impulse」を押すと、左側のメニューに「Image」という項目が出ているはずです。
そこをクリックします。

  1. Parameters設定:
    • 通常は「Color depth」が「RGB」になっていることを確認するだけでOKです。
  2. Generate features:
    • 緑色の「Generate features」ボタンをクリックします。
    • クラウド上で計算が走り、数秒〜数十秒で完了します。

2. 確認:Feature Explorer(3Dグラフ)を見る

計算が終わると、画面の右側に3色の点が散らばった3Dグラフ(Feature Explorer)が表示されます。

ここがこの工程の最重要ポイントです。
このグラフを見ることで、「このAIが成功しそうか、失敗しそうか」が学習前に分かります。

  • 何を表している?:
    • 1つの点 = 1枚の画像データ です。
    • 点の色 = ラベル(Aさん、Bさん、背景)を表しています。
    • 点の距離 = 「AIから見たときの似ている度合い」 です。
      近くにある点は「似ている」、遠くにある点は「似ていない」ことを意味します。

成功のサイン(良いグラフ)

  • 色がきれいに分かれている:「青い点(Aさん)の固まり」と「オレンジの点(Bさん)の固まり」が、離れた場所に別々の島を作っている状態。
    • 意味: AIにとって、AさんとBさんの違いが明確に見えています。これなら高精度が期待できます。

失敗のサイン(悪いグラフ)

  • 色が混ざり合っている:青い点とオレンジの点が入り乱れて、一つの大きな固まりになっている状態。
    • 意味: AIには区別がついていません。このまま学習させても、判定を間違える可能性が高いです。
    • 対処法: 写真を撮り直すか、背景が似すぎていないか確認する必要があります。

まとめ

このステップの役割は以下の2つです。

  1. 変換: 画像を数値データにする。
  2. 診断: 3Dグラフを見て、データが適切に分離できているかチェックする。

もし3Dグラフできれいに色が分かれていれば、準備は完璧です!

いよいよ最後の仕上げ、「Transfer Learning(実際の学習)」に進んで、AIモデルを完成させましょうか?

学習の作業

Transfer Learning(実際の学習)の作業について教えてください

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

いよいよAI開発のクライマックス、「Transfer Learning(転移学習)」の工程ですね。

ここで、これまで準備したデータを使って、実際にAIモデルをトレーニング(訓練)します。

「転移学習」とは、例えるなら「すでに視力の良いベテランの探偵に、新しい犯人の顔写真を見せて『この人を探して』と依頼する」ようなものです。

ゼロから教育するのではなく、すでに「物の形や色を見分ける基礎能力」を持ったAI(学習済みモデル)をベースにするため、少ないデータと短い時間で、非常に精度の高いAIを作ることができます。

具体的な設定手順と、結果の見方を解説します。

1. 設定画面(Neural Network settings)

左メニューの「Transfer Learning」をクリックすると設定画面が出ます。いじりすぎると沼にハマるので、まずは以下の3点だけに注目してください。

  1. Number of training cycles (Epochs):
    • 意味: 教科書を何周読むか(学習の繰り返し回数)です。
    • 推奨値: デフォルト(通常20〜50回)のままでOKです。もし精度が悪ければ少し増やします。
  2. Learning rate:
    • 意味: 学習のペース配分です。
    • 推奨: デフォルトのままでOKです。
  3. Data augmentation (データの水増し): ★重要
    • 意味: ここにチェックを入れると、学習中に画像を勝手に「少し斜めにする」「拡大する」「ノイズを入れる」といった加工を行い、データを擬似的に増やしてくれます。
    • 推奨: 必ずチェックを入れてください。 これにより、実際にカメラを向けた時の手ブレや角度の違いに強いAIになります。

2. モデルの選択(Choose a model)

画面の下の方に、ベースとなるAIモデルを選ぶリストがあります。

  • MobileNetV2 (推奨):
    • Arduinoなどのマイコン向けに最適化された、軽量かつ高性能なモデルです。
    • リストの中から、MobileNetV2 96x96 0.35 のような名前のものを選びます。
      • 0.35 などの数字は「モデルの大きさ」です。数字が小さいほど高速ですが、少しおバカになります。数字が大きいほど賢いですが、処理が遅くなります。
      • 最初は 0.10.35 あたりから試すのがArduino UNO R4には適しています。

3. 学習開始と評価

「Start training」ボタンを押すと、画面右側でログが流れ始めます。
数分待つと学習が完了し、成績表が表示されます。

成績表の見方(超重要)

結果画面に表示される「Confusion Matrix(混同行列)」という表を見てください。

  • Accuracy (正答率): 全体のテストで何%正解したか。80〜90%以上あれば合格ラインです。
  • 表の見方:
    • 縦軸が「正解(本当は誰か)」、横軸が「AIの予測(誰だと思ったか)」です。
    • 対角線上の数字(左上から右下へのライン)が高い数字になっていれば成功です。
    • 例: 「Aさん」の行を見て、「Bさん」の列に数字が入っていたら、「AさんなのにBさんと間違えた」ことを意味します。

まとめ

  1. Data augmentationをオンにする。
  2. MobileNetV2(0.1か0.35)を選ぶ。
  3. Start trainingを押す。
  4. Confusion Matrixを見て、誤判定が少ないかチェックする。

もしAccuracyが低い(例えば60%くらい)場合は、「特徴抽出」の時の3Dグラフが混ざっているか、モデルのサイズが小さすぎる可能性があります。その際はモデルの数字(0.35 → 0.1 等)を変えて再トライしてみてください。

この学習が終われば、いよいよArduinoに書き込むためのファイルをダウンロード(デプロイ)できます。

デプロイ作業

Arduinoに書き込むためのファイルをダウンロード(デプロイ)する作業について説明してください

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

いよいよEdge Impulseでの最後の工程、「デプロイ(Deployment)」ですね。

これは、クラウド上で完成した「AIの脳みそ」を、Arduinoが理解できる「ライブラリ(ZIPファイル)」という形にパッケージ化してダウンロードする作業です。

この作業が終われば、ブラウザでの作業は完了し、Arduino IDE(開発環境)での作業に移ります。
手順と、プロならではの設定ポイントを解説します。

1. デプロイ画面への移動と選択

  1. Edge Impulseの左メニューから「Deployment」をクリックします。
  2. 検索バー(Search deployment options)に「Arduino」と入力します。
  3. 「Arduino library」 という項目が表示されるので、これを選択します。

なぜ「Arduino library」なのか?

他にも「Firmware(ファームウェア)」という選択肢がありますが、これは「書き込んだらそれしかできない」専用ソフトになってしまいます。

今回のように「顔認識もしつつ、Web UIも表示したい」という場合は、他のプログラムと合体できる「Library(部品)」としてダウンロードする必要があります。

2. 最適化設定(Optimization settings) ★重要

画面の下に、モデルの変換タイプを選ぶ項目があります。
ここでArduino UNO R4向けに最適な設定を選びます。

  • Enable EON Compiler:
    • デフォルトでONになっています。これはメモリを節約する強力な機能なので、必ずONのままにしてください。
  • Model optimization:
    • Quantized (int8)【強く推奨】
      • 数値を少し粗く(整数化)して、サイズを小さく、動作を高速にします。Arduinoのようなマイコンでは、こちらを選ばないとメモリ不足で動かないことがよくあります。精度はほとんど落ちません。
    • Unoptimized (float32)
      • PCなどの高性能な計算機用です。Arduinoには重すぎます。

3. ビルドとダウンロード(Build)

  1. 設定を確認したら、最下部の「Build」ボタンをクリックします。
  2. サーバー上でコンパイル(変換作業)が始まります。1〜2分ほどかかります。
  3. 完了すると、ブラウザが自動的にZIPファイル(例:ei-project-name-arduino-1.0.0.zip)をダウンロードします。

注意: ダウンロードされたZIPファイルは、解凍(展開)しないでください。 そのままの状態で使用します。

4. Arduino IDEへの取り込み方

ダウンロードしたファイルは、以下の手順でArduino IDEにインストールします。

  1. PCで Arduino IDE を起動します。
  2. メニューバーから [スケッチ] -> [ライブラリをインクルード] -> [.ZIP形式のライブラリをインストール…] を選択します。
  3. 先ほどダウンロードしたZIPファイルを選択して「開く」を押します。
  4. 画面下に「ライブラリが追加されました」と表示されれば成功です!

これで「脳みそ」の準備は完了です

おめでとうございます! これであなたのPCの中には、「特定の顔を判別できる専用のAIライブラリ」が入りました。

あとは、最初に提案した video_objectdetection Brick のコードを書き、このライブラリを呼び出すように少し修正するだけで、オリジナルの顔認証アプリが動き出します。

ここまでの流れで、Edge Impulse側での作業はすべて完了です。

次は、Arduino IDEで実際にコードを書く(Bricksを組み立てる)フェーズに進みますか?

ライブラリ呼び出しのためのBrickコード修正

Brick のコードを、このライブラリを呼び出すように修正する方法は分かりますか

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

はい、その手順は完全に把握しています。任せてください。

「Brickのコードを修正する」と考えると難しく感じるかもしれませんが、実はEdge Impulseが生成したライブラリの中に「正解のカンニングペーパー(サンプルコード)」が入っています。 これをベースにするのが最も近道です。

以下に、技術的な修正ポイントと、具体的なコードの書き方を解説します。

1. ベースとなるコードの準備

ゼロから書くのではなく、インストールしたライブラリのサンプルを開きます。

  1. Arduino IDEのメニューから [ファイル] -> [スケッチ例] を開きます。
  2. 下の方にスクロールすると、「あなたのプロジェクト名(Edge Impulseで付けた名前)」 の項目があります。
  3. その中の nano_ble33_sense_camera (または単に camera)という名前のサンプルを選んで開いてください。
    • ※UNO R4 WiFiの場合でも、カメラ制御の基本ロジックはこのサンプルがベースになります。

2. コードの修正箇所(Brickの統合)

このサンプルコードは、「カメラ画像をAIに渡して、結果をシリアルモニタ(文字)で表示する」ところまで書かれています。

これを、「結果を判定して、Web UI Brickに渡す」ように書き換えます。

コードの末尾の方にある void loop() 内の、結果表示部分(ei_printfなどが書かれている場所)を以下のように改造します。

修正イメージ(概念コード)

C++

// ★重要: ライブラリのヘッダー読み込み(サンプルに最初から書かれています)
#include <あなたのプロジェクト名_inferencing.h> 

// ... (セットアップなどのコードはそのまま) ...

void loop() {
    // ... (画像撮影と推論の処理はそのまま) ...

    // ▼▼▼ ここからが修正ポイント ▼▼▼

    // 推論結果(result)の中に、それぞれの確率が入っています
    // 例: Aさん(0.1), Bさん(0.85), 背景(0.05)
    
    String detectedName = "Unknown";
    float maxConfidence = 0.0;

    // 全てのラベル(Aさん、Bさん、背景)をループしてチェック
    for (size_t ix = 0; ix < EI_CLASSIFIER_LABEL_COUNT; ix++) {
        
        // 確率(value)を取得
        float confidence = result.classification[ix].value;
        
        // 確率が一番高い人を見つける
        if (confidence > maxConfidence) {
            maxConfidence = confidence;
            detectedName = result.classification[ix].label; // 名前を保存
        }
    }

    // --- ここでアプリの動作を決定 ---
    
    // 閾値(例: 70%以上)を超えていれば「特定できた」とみなす
    if (maxConfidence > 0.7) {
        
        // 【Brick連携】 Web UIに結果を送る
        // updateWebUI(detectedName, maxConfidence); 
        
        // もし「背景(Background)」なら何もしない、などの分岐もここで書けます
        if (detectedName != "Background") {
            Serial.print("発見!これは ");
            Serial.println(detectedName);
            Serial.println(" です!");
        }
    }

    // ▲▲▲ 修正ポイントここまで ▲▲▲

    delay(100); // 少し待機
}

3. 解説:何が変わったのか?

  • Before: 単に「Aさん: 10%, Bさん: 90%」と文字を垂れ流していただけ。
  • After:
    1. result.classification という配列からデータを数値として取り出しました。
    2. if (maxConfidence > 0.7) という「判断基準(閾値)」を設けました。
    3. この判断の後に updateWebUI() のような関数(Web UI Brickの機能)を呼ぶことで、スマホ画面に「Bさんです!」と表示できるようになります。

次のステップ

これで「脳みそ(AI)」と「体(コード)」をつなぐ設計図はできました。

次は、実際に「判定結果をスマホ画面にカッコよく表示する Web UI Brick のコード」(HTML/CSSを含んだArduinoコード)を具体的に作成しましょうか? それとも、カメラの接続などハードウェア面で確認したいことはありますか?

Web UI Brick コード作成

判定結果をスマホ画面にカッコよく表示する Web UI Brick のコードを作成してください

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

承知いたしました。「判定結果をスマホ画面にカッコよく表示する」ための Web UI Brick のコードを作成しました。

今回は、SF映画のセキュリティモニターのような「ダークモード」を基調とし、認識した人物の名前と信頼度(確信度)をリアルタイムでアニメーション表示するデザインに仕上げています。

このコードは、Arduino UNO R4 WiFiの標準ライブラリ(WiFiS3)で動作するように設計しています。

Web UI Brick (Code: SimpleSecurityUI)

このコードを、あなたのスケッチ(プログラム)の最後尾に追加するか、新しいタブに貼り付けてください。

1. 設定とHTMLデータ(グローバル変数エリア)

C++

#include <WiFiS3.h>

char ssid[] = "YOUR_WIFI_SSID";      // ★あなたのWi-Fi名に変更
char pass[] = "YOUR_WIFI_PASSWORD";  // ★あなたのWi-Fiパスワードに変更

WiFiServer server(80);

// 現在の認識結果を保存する変数
String currentName = "Searching...";
int currentConfidence = 0;

// ▼▼▼ スマホに表示するHTML/CSS/JSコード ▼▼▼
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Arduino AI Eye</title>
  <style>
    body { background-color: #121212; color: #ffffff; font-family: 'Courier New', monospace; text-align: center; margin: 0; padding: 20px; }
    .container { max-width: 400px; margin: auto; border: 2px solid #333; border-radius: 15px; padding: 20px; background: #1e1e1e; box-shadow: 0 0 20px rgba(0, 255, 127, 0.2); }
    h1 { color: #00ff7f; font-size: 24px; text-transform: uppercase; letter-spacing: 2px; border-bottom: 1px solid #333; padding-bottom: 10px; }
    .status { font-size: 14px; color: #888; margin-bottom: 30px; }
    .result-box { margin: 30px 0; }
    .label { font-size: 16px; color: #aaa; }
    #name-display { font-size: 42px; font-weight: bold; margin: 10px 0; color: #fff; text-shadow: 0 0 10px rgba(255,255,255,0.5); }
    .bar-container { width: 100%; background-color: #333; border-radius: 10px; overflow: hidden; margin-top: 10px; height: 25px; }
    #conf-bar { height: 100%; width: 0%; background: linear-gradient(90deg, #00ff7f, #00cc66); transition: width 0.3s ease; }
    .conf-text { margin-top: 5px; font-size: 12px; color: #00ff7f; }
    .footer { margin-top: 40px; font-size: 10px; color: #555; }
  </style>
</head>
<body>
  <div class="container">
    <h1>Security Monitor</h1>
    <div class="status">SYSTEM: <span style="color:#00ff7f">ONLINE</span></div>
    
    <div class="result-box">
      <div class="label">DETECTED TARGET</div>
      <div id="name-display">...</div>
    </div>

    <div class="label">CONFIDENCE</div>
    <div class="bar-container">
      <div id="conf-bar"></div>
    </div>
    <div class="conf-text" id="conf-val">0%</div>

    <div class="footer">ARDUINO UNO R4 EDGE AI SYSTEM</div>
  </div>

  <script>
    // 0.5秒ごとに最新データを取得する
    setInterval(function() {
      fetch("/json")
        .then(response => response.json())
        .then(data => {
          // 名前を更新
          const nameEl = document.getElementById("name-display");
          nameEl.innerText = data.name;
          
          // 色を変える演出 (Backgroundなら灰色、人なら白)
          if(data.name === "Background" || data.name === "Unknown") {
             nameEl.style.color = "#555";
             document.querySelector(".container").style.boxShadow = "none";
          } else {
             nameEl.style.color = "#fff";
             document.querySelector(".container").style.boxShadow = "0 0 20px rgba(0, 255, 127, 0.4)";
          }

          // 信頼度バーを更新
          document.getElementById("conf-bar").style.width = data.conf + "%";
          document.getElementById("conf-val").innerText = data.conf + "%";
        });
    }, 500); 
  </script>
</body>
</html>
)rawliteral";

2. 組み込み用関数(セットアップとループ)

これを既存のコードに統合するための関数です。

C++

// setup() の中で一度だけ呼ぶ
void setupWebUI() {
  Serial.print("Connecting to WiFi...");
  WiFi.begin(ssid, pass);
  
  // Wi-Fi接続待ち
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected.");
  Serial.print("Access this URL: http://");
  Serial.println(WiFi.localIP()); // ★シリアルモニタに表示されたIPアドレスにスマホからアクセス

  server.begin();
}

// loop() の中で毎回呼ぶ (AIの判定結果を渡す)
void handleWebUI(String name, float confidenceVal) {
  // グローバル変数を更新(HTML側が読み取るため)
  currentName = name;
  currentConfidence = (int)(confidenceVal * 100);

  WiFiClient client = server.available();
  if (client) {
    String currentLine = "";
    String request = "";
    
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        request += c;
        if (c == '\n') {
          if (currentLine.length() == 0) {
            
            // リクエストの振る分け
            if (request.indexOf("GET /json") >= 0) {
              // データだけをJSON形式で返す (JavaScriptがこれを読む)
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: application/json");
              client.println("Connection: close");
              client.println();
              client.print("{\"name\":\"");
              client.print(currentName);
              client.print("\",\"conf\":");
              client.print(currentConfidence);
              client.println("}");
            } else {
              // メインの画面(HTML)を返す
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println("Connection: close");
              client.println();
              client.println(index_html);
            }
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
  }
}

統合の仕方(まとめ)

前回のコード修正案と合わせると、全体の流れはこうなります。

  1. 先頭: 上記の「1. 設定とHTMLデータ」を貼り付ける。
  2. setup()内: setupWebUI(); を追加する。
  3. loop()内:AIの判定ロジックの後(if (maxConfidence > 0.7) のあたり)で、以下のように呼び出します。

    C++

// AIの判定結果をWeb UIに渡す
// detectedName: 認識した名前
// maxConfidence: 信頼度(0.0〜1.0)
handleWebUI(detectedName, maxConfidence);

デザインのポイント

  • サイバーパンク風: 黒背景にネオングリーンの文字で、プロっぽいセキュリティシステム感を演出しました。
  • 非同期通信 (AJAX): 画面全体を再読み込みするのではなく、JavaScriptが裏でデータだけを取りに行くので、画面がチカチカせずスムーズに数値が変化します。
  • 視覚フィードバック: 「背景」のときは暗く、「人」を見つけたときは画面の枠がボワッと光るエフェクトを入れています。

これを書き込んでシリアルモニタに出るIPアドレス(例: 192.168.1.15)にスマホでアクセスすれば、あなたの作ったAIアプリが手元で動きます!

実装してみて、もし「文字の大きさを変えたい」「色を変えたい」などの要望があれば、CSS部分の調整方法もお教えしますよ。

画像生成AIによる水増し画像の可能性

データ収集の方法として動画を使う方法が手軽で良い方法であることは分かったのですが、画像生成AIの性能も上がってくるので、画像生成AIで人の画像を水増しする方法についてさらに質問したいと思います。画像生成AIで水増しされた人画像でも、正答率が80%〜90%以上出ていれば使えるということでしょうか

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

非常に鋭い、そして現代的な視点のご質問です。「画像生成AIで水増ししたデータでも、スコア(正答率)が良ければ使えるのか?」という点ですね。

結論から申し上げますと、「Edge Impulse上の正答率が80〜90%であっても、現実世界では全く使い物にならない(認識しない)ケースがある」というのが、プロとしての正直な回答です。

なぜ「数字が良いのに使えない」という現象が起きるのか、そして「生成AIを使う場合の正しい検証ルール」について解説します。

1. なぜ「90%」が嘘をつくのか?(生成AIの落とし穴)

もし、あなたが「生成AIで作った画像」を学習データ(Train)テストデータ(Test)の両方に入れてしまった場合、以下のような事態が起こります。

  • 現象: AIは「あなたの顔の特徴」ではなく、「生成AI特有の画質やノイズ(アーティファクト)」を「あなたの顔だ」と勘違いして学習します。
  • 結果:
    • Edge Impulse上のテスト結果: 99%(大成功!)
    • 実機(カメラ)での動作: 0%(全く反応しない)
  • 理由: 実際のカメラ映像には、生成AI特有のノイズが含まれていないため、AIにとっては「見たことがない未知のデータ」に見えてしまうのです。

2. 生成AIを使う場合の「鉄の掟」

しかし、生成AIを使うこと自体がダメなわけではありません。「テストデータの扱い方」さえ間違えなければ、有効に活用できます。

もし画像生成AIでデータを水増しする場合、以下のルールを絶対に守ってください。

【鉄の掟】 テストデータ(検証用データ)には、1枚たりとも生成AI画像を入れてはいけない。「100% 実写」でなければならない。

正しい構成例

  • 学習用データ (80%): 実写 + 生成AI画像(水増し分)
  • テスト用データ (20%): すべて実写(カメラで撮ったもの)

この状態で「Accuracy 80〜90%」が出るのであれば、その生成AI画像は「効果がある(使える)」と判断できます。

逆に、テストデータに生成AI画像を混ぜて出した高得点は、参考になりません(これを「データ・リーク」と呼びます)。

3. 生成AIでの水増しが「有効なケース」と「無効なケース」

顔認証において、生成AI(Stable DiffusionのImg2ImgやControlNetなど)を使う場合の効果的な使い分けです。

生成タイプ有効性理由
照明・環境の変化◎ 高い実写の顔写真をベースに、背景を「夜にする」「森にする」、照明を「逆光にする」などの加工は、AIの適応力を高めます。
ノイズ・画質劣化○ あるあえて「画質を悪くする」「ボケさせる」生成は、低解像度カメラ対策として有効です。
表情・角度の変更△ 危険「真顔」から「笑顔」や「横顔」を生成させると、目鼻の距離などの生体特徴(Biometrics)が微妙に変わり、別人として学習されるリスクが高いです。

4. Architectからの結論と提案

結論:

「生成AI画像を使っても、実写のみのテストデータで80〜90%が出るなら、それは本物です。使えます。」

提案:

もし、画像生成AI技術にも興味がおありでしたら、まずは「ハイブリッド実験」をしてみませんか?

  1. まず、「動画切り出し(実写のみ)」でモデルを作る(基準スコアを出す)。
  2. 次に、そのデータをコピーし、「背景(Background)」クラスだけを生成AIで大量に作った画像(宇宙、ジャングル、極彩色の部屋など)に差し替えて学習させてみる。

これなら、顔の誤認識リスクを冒さずに、「AIが誤反応しにくい最強のモデル」を作れる可能性が高いです。

この実験的なアプローチで進めてみますか? それとも、まずは確実な「実写動画のみ」でアプリを完成させてしまいますか?

動画から有効フレーム抽出

20秒程度の動画ファイルから、学習に有効な300フレームの画像を抽出して保存してくれるアプリを作ることができると思いますか

Architect(Gemini 3 Pro)の回答

こんにちは。Arduino App Lab Architectです。

はい、可能です。そして、それは非常に素晴らしいアイデアです。

実は、AI開発の現場では、モデルを作る時間よりも「良質なデータを作るツール(スクリプト)を作る時間」の方に多くのリソースを割くことがよくあります。

動画ファイルから「ただ画像を切り出す」だけでなく、「学習に有効な(良質な)画像を厳選して保存する」 アプリ(PC上で動くツール)を作成することは、Pythonという言語とOpenCVというライブラリを使えば、驚くほど短いコードで実現できます。

このツールの仕様と、具体的なコードを提案します。

「学習に有効な画像」とは何か?

20秒の動画には通常600枚(30fps)の画像が含まれますが、全部使う必要はありません。
以下の条件を満たす300枚を抽出するロジックを組み込みます。

  1. 多様性(Diversity):動画の最初から最後まで、均等に時間を空けて抽出する。
    (例:0秒目、0.1秒目、0.2秒目…とスキップする)ことで、似たような画像ばかりになるのを防ぎます。
  2. 鮮明さ(Blur Detection):カメラが素早く動いた時の「ブレた画像(ピンボケ)」はAIの学習を邪魔します。
    これを自動検知して捨てます。

データセット作成支援ツール (Python Script)

このコードは、Arduinoではなく、あなたのPC(Windows/Mac)で実行します。

動画ファイル(input.mp4)と同じ場所に置いて実行すると、自動的にフォルダを作って綺麗な画像だけを保存します。

必要な準備:

PCにPythonがインストールされている状態で、以下のコマンドでライブラリを入れます。

pip install opencv-python

コード (frame_extractor.py):

Python

import cv2
import os

# ==========================================
# 設定エリア
# ==========================================
VIDEO_PATH = 'input.mp4'      # 読み込む動画ファイル名
OUTPUT_DIR = 'dataset_output' # 保存先フォルダ名
TARGET_COUNT = 300            # 欲しい枚数
BLUR_THRESHOLD = 100.0        # ブレ判定の厳しさ(低いほど厳しく、高いほど緩い。通常100〜150)
# ==========================================

def extract_frames():
    # 動画を読み込む
    cap = cv2.VideoCapture(VIDEO_PATH)
    if not cap.isOpened():
        print("エラー: 動画ファイルが見つかりません。")
        return

    # 動画の情報を取得
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    
    # 全フレームから均等にTARGET_COUNT枚を取り出すためのステップ数(間隔)
    # ブレて捨てられる分を見越して、少し細かめ(0.8掛け)に間隔を設定
    step = max(1, int((total_frames / TARGET_COUNT) * 0.8))

    if not os.path.exists(OUTPUT_DIR):
        os.makedirs(OUTPUT_DIR)

    count = 0
    saved_count = 0
    
    print(f"処理開始: 全 {total_frames} フレームから、良質な画像を抽出します...")

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        # 指定した間隔のフレームだけをチェック対象にする
        if count % step == 0:
            # 1. 画像をグレーにしてブレ判定(ラプラシアン分散)を行う
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            score = cv2.Laplacian(gray, cv2.CV_64F).var()

            # 2. スコアが閾値以上(鮮明)なら保存
            if score > BLUR_THRESHOLD:
                # 96x96などのリサイズはEdge Impulse側でやるので、ここでは高画質のまま保存推奨
                filename = os.path.join(OUTPUT_DIR, f"img_{saved_count:04d}.jpg")
                cv2.imwrite(filename, frame)
                saved_count += 1
                print(f"保存: {filename} (鮮明度スコア: {int(score)})")
            else:
                print(f"スキップ: ブレ検知 (スコア: {int(score)})")

            # 目標枚数に達したら終了
            if saved_count >= TARGET_COUNT:
                break

        count += 1

    cap.release()
    print("------------------------------------------")
    print(f"完了! 合計 {saved_count} 枚の画像を {OUTPUT_DIR} に保存しました。")

if __name__ == "__main__":
    extract_frames()

このツールのポイント(技術解説)

  1. ラプラシアン分散 (cv2.Laplacian):
    • 画像の「エッジ(輪郭)」がどれくらいハッキリしているかを数値化する数学的な手法です。
    • ピンボケ写真はエッジがぼやけるため、この数値が低くなります。
      これを利用して「AIが学習しやすいクッキリした画像」だけを選別しています。
  2. 均等抽出:
    • 20秒の動画の「最初の5秒」だけで300枚集めても意味がありません。
      動画全体の長さに合わせて自動的にスキップ幅(Step)を計算し、あらゆる角度を網羅できるようにしています。

実は Edge Impulse にも…?

正直にお伝えしますと、Edge Impulseのブラウザ画面上にも「Upload Video」という機能があり、動画をアップロードすると自動でフレームに分割してくれる機能自体は備わっています。

しかし、自作ツールのメリットは大きいです:

  • Edge Impulseの機能: 単純に「○秒ごとに分割」するだけで、ブレている画像も全部保存されてしまいます。
    後から手動でゴミ箱に入れる作業が発生します。
  • 今回の自作ツール: PC上で「ブレている画像」を事前にカットできるため、Edge Impulseにアップロードした後の仕分け作業(Data Cleaning)が劇的に楽になります。

このPythonスクリプトを使って、効率的にデータを量産してみますか? もしPythonの環境構築が手間であれば、その手順もサポートします。

顔データを作成するのに結構手間がかかることが分かった。玄関などの決まった場所で、昼間及び夜間に数名の家族を登録し、家族と他人とを識別する程度の用途には使えそうだ。
撮影される人物にその場で回ってもらい、10秒間の内に、ななめ上方やななめ下方から、ブレずに動画を撮るのは結構難しい。

目次