顔検出

写真(静止画)を使って顔検出する方法を紹介します。顔検出には、専用のノード(face-recognition)を使用します。ボックスで顔を囲むだけでなく、各種パラメータを取得できます。

必要なノード

下記のノードをパレットから追加します。

  • node-red-node-base64
  • node-red-contrib-face-recognition
  • node-red-contrib-image-output

インターネット上の画像から顔検出

ネット上の画像を読み込み顔検出する方法を紹介します。画像のURLを指定すると、顔検出した結果を表示します。

※画像が表示されているページのURLではなく、画像そのもののURLを指定してください。

以下にフローを示します。

手順(フローの説明)

  1. injectノードを使って画像のURLを指定します。
    たとえば、[https://aikido-heiseikai.jp/wp-content/uploads/2023/06/DSC_0017.jpg] などを指定して下しさい。上記の例です。
  2. changeノードを使って、入力された文字列(画像のURL)を、msg.url に代入します。
  3. http-requestノード、メソッドGETを使ってインターネットから画像を取得します。
  4. face-api-input ノードを使って顔検出します。
  5. changeノードを使って、msg.payload.labelled_imgをmsg.payloadに代入します。
  6. base64ノードを使って、バッファ<->base64の変換を行います。
  7. templeateノードを使って、<img src=”data:image/png;base64,{{msg.payload}}”>として、ダッシュボードに表示します

imageノードを使うと、フロー中で画像を確認することができます。debugノードの画像版だと考えると良いです。入力画像(左側)は、取得画像をそのままmsg.payloadで表示、ボックス付き画像(右側)は、顔検出後のmsg.payload.labelled_imgを表示させます。

※顔検出ノード(face-api-input)のパラメータは以下の通りです。状況に合わせて変更してください。

参考のフローです。face1_flowsダウンロード後、拡張子をjson に書き換えてください。

 


USBカメラの画像(静止画)からの顔検出

システム構成は、次の通りとして全体設計を行います。USBカメラで撮影した写真(静止画)をフロアマネージャー(サーバー)へ画像ファイルとして、MQTTで、数秒間隔で送ります。フロアマネージャで受け取った画像を処理し、フロアマネージャからダッシュボードを通して、元画像と顔検出画像を表示します。
送る間隔はサーバー機器の性能により調整してください。フロアマネージャーとして一昔前のパソコンの再利用だと、4,5秒間隔が適当です。

必要なノード

USBカメラ側(PDH側)のNode-REDのパレットから以下のノードを追加します

  • node-red-contrib-usbcamera

フロアマネージャ側は、上記のインターネット画像の項のノードがインストールされている事が前提です。

カメラ側の手順

  1. injectノードを使って撮影間隔(4~5秒程度)を指定します。
  2. usbcameraノードを使って撮影します。file ModeはBufferに設定します。サイズは640×480程度がお勧めです。
  3. mqtt-outノードを使って画像を送信します。サーバーアドレス、ポート番号(1883)、トピックを指定します。

フロアマネージャ(サーバー)側の手順

  1. mqqt-inノードを使って画像を受信します。サーバーアドレス、ポート番号(1883)、トピックを指定します。
  2. この後は、face-api-input ノードを使って、上記インターネット画像の項と同じように処理します。

カメラ画像(静止画)からの特徴量の抽出

想定アプリケーション

カメラ画像の中から顔検出し、その数(人数)を数える。人数を数えて、混み具合を計測する。

手順

  1. mqqt-inノードを使って画像を受信します。
  2. face-api-input ノードを使って顔検出します。
  3. face-api-input ノードの出力から、顔検出したボックスの数を数えます。
    検出した顔の情報(ボックスの情報)はmsg.payload.detected_facesにarrayとして返されますので、その長さをmsg.payload.detected_faces.lengthとして取得します。下記の事例では16(数字)が返されます。

ちなみに、ラベルの付いた画像(ボックスが付いた画像)は、msg.payload.labelled_imgとして出力されます。


 

トラブルシューティング

以下のように、顔検出ノードで、ERR_IPC_CHANNNEL_CLOSED なるエラーが発生する場合があります。原因はハードウエアのCPUに依存するようで、実績としてはインテルのi5では問題ないようですがCeleronではエラーが発生します。