Vol.761 11.Jan.2019

2軸サーボ制御用カメラ台 ラズベリーパイ(25)〜OpenCVで顔認識&カメラ制御〜 シュピーレンの収納_etc

C 2軸サーボ制御用カメラ台

by fjk

abc760で使ったカメラ台はカメラが前方に飛び出し、しっかりと固定しないと不安定である。そこで、フリーのstlデータを参考に形状を修正し、新たに3Dプリンタを使ってカメラ台を作成した。サーボモータ(SG-90)の取付にはサーボ付属のホーンを加工無く使う構造とした。
 カメラ台用stlデータ(camera-sg90.zip)
作成したパーツ サーボにホーンを取付 パーツを組上げネジで固定


R ラズベリーパイ(25) 〜OpenCVで顔認識&カメラ制御〜

by fjk

画像処理が行えるOpenCV(CompuerVision)を使って、ラズパイカメラで取り込んだ画像の中で、人の顔の検出を行い、カメラの中心になるようにモータを制御する。
 書籍「実例で学ぶRaspberryPi電子工作」(講談社)を参考にした。

1.OpenCVのインストール
$ sudo apt-get update
$ sudo apt-get install libopencv-dev python-opencv

2.OpenCVによる画像処理の例
画像処理前 2値化 エッジ検出
原画(Lena)512x512 円検出(ライト、赤丸) 顔検出(赤角)

3.顔認識とサーボモータ制御
サーボモータ制御にはpigpioを(参考書ではwiringpi)、カメラはラズパイカメラを使用。
$ sudo pigpiod  ・・でpigpioデーモンを先に起動しておく
$ python tracking-face.py

顔認識&サーボ制御 <tracking-face.py
# -*- coding: utf-8 -*-
import picamera
import picamera.array
import cv2
import math
import pigpio

cascade_path =  "/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"
cascade = cv2.CascadeClassifier(cascade_path)

pi = pigpio.pi()

# === サーボ用定数
Pan  = 17            # 左右サーボ接続ピン
Tlt   = 18            # 上下サーボ接続ピン
Pan_hm  = 1500
Tlt_hm  = 1500
Pan_max = 2000       # Pan動作範囲
Pan_min = 1000
Tlt_max = 1700        # Tilt動作範囲
Tlt_min = 1200

# === 画像用定数
Width_x = 320         # 画像の横画素数
Width_y = 240         # 画像の縦画素数
Cent_x  = Width_x / 2
Cent_y  = Width_y / 2
Ratio_x = 1.0          # 画素数とサーボ移動量の比
Ratio_y = 1.0

# === 初期化
pan_pos = Pan_hm      # サーボを初期位置に
tlt_pos  = Tlt_hm
pi.set_servo_pulsewidth(Pan, pan_pos)
pi.set_servo_pulsewidth(Tlt, tlt_pos)

with picamera.PiCamera() as camera:
  with picamera.array.PiRGBArray(camera) as stream:
    camera.resolution = (Width_x, Width_y)

    while True:
      camera.capture(stream, 'bgr', use_video_port = True)        # stream.arrayにBGRの順で映像データを格納
      gray = cv2.cvtColor(stream.array, cv2.COLOR_BGR2GRAY)   # 映像データをグレースケール画像grayに変換
      # === grayから顔を探す
      facerect = cascade.detectMultiScale(gray, scaleFactor = 1.3, minNeighbors = 2, minSize = (30,30), maxSize = (150,150))

      if len(facerect) > 0:      # 顔が見つかったら、複数見つかった顔のうち、画像中心に最も近いものを探す
        mindist = Width_x+Width_y
        minindx = 0
        indx = 0
        for rect in facerect:
          dist = math.fabs(rect[0] + rect[2]/2 - Cent_x) + math.fabs(rect[1] + rect[3]/2 - Cent_y)
          if dist < mindist:     # より近距離の顔が見つかった?
            mindist = dist
            minindx = indx
          indx += 1

        # === 現在の顔の位置(枠の中心)
        face_x = facerect[minindx][0] + facerect[minindx][2]/2
        face_y = facerect[minindx][1] + facerect[minindx][3]/2

        # === 元の画像(system.array)上の、顔がある位置に赤い四角を描画
        cv2.rectangle(stream.array, tuple(facerect[minindx][0:2]), tuple(facerect[minindx][0:2]+facerect[minindx][2:4]), (0,0,255), thickness=2)

        dx = int(((Cent_x - face_x) * Ratio_x)/10)*10  # 左右中央からのずれ。(移動方向が逆なら項を入れ替)※
        dy = int(((face_y - Cent_y) * Ratio_y)/10)*10  # 上下中央からのずれ。(移動方向が逆なら項を入れ替)※

        # === サーボモーターの移動許容範囲でモータを回転
        if Pan_min <= pan_pos + dx <= Pan_max:
           pan_pos += dx
           pi.set_servo_pulsewidth(Pan, pan_pos)
        if Tlt_min <= tlt_pos + dy <= Tlt_max:
           tlt_pos += dy
           pi.set_servo_pulsewidth(Tlt, tlt_pos)

      # === system.array(画像)をウインドウに表示
        cv2.imshow('frame', stream.array)

      # === "q"を入力でアプリケーション終了
      if cv2.waitKey(1) & 0xFF == ord('q'):
        break

      # === streamをリセット
      stream.seek(0)
      stream.truncate()

    cv2.destroyAllWindows()   # 顔認識スケッチを終了
# ※ノイズ対策のため、10より小さいズレは無視。

顔認識テスト中


S シュピーレンの収納 etc

by fjk

  1. 自動車用工具・オーニング用ハンドル (ステップ部に配線固定具とマジックベルト止め)
  2. 地図、書籍、マニュアルなど (スクリューネジで百均A4書類ケースをボードに固定)
  3. 目隠し (後部にはカーテン、サイドガラスにはフイルム)
  4. 外部電源コード・シューズカバー・車用工具関係 (コンテナに収納)
  5. エントランス (フロアマットをエントランスに固定し、雨天時には車内で靴の脱着ができる)、脱いだ靴はシート下においたトレーに収納
  6. 滑り止め (左右のテーブルの上においてテッシュ・救急セットなどの小物の滑り防止)
  7. シュラフ (寝袋非使用時はクッションに、2枚セット)、 空気枕 (吊棚収納)
  8. マルチシェード (折り畳み後、紐で縛って百均収納袋に入れて寝床下に収納)
  9. シフトレバー照明 (4連ソケットを灰皿に両面テープで固定し、ソケットにLEDライト)
  10. 事務用品 (自立型筆箱を両面テープ止めした百均ケースに、スマホケースには付箋紙を)
  11. 時計 (電池式目覚まし機能付き時計をマジックテープで壁に固定)
  12. ナイトライト (充電式、マジックテープで壁に固定) ・電池式ランタン (懐中電灯も兼ねる)
  13. ルーフ用脚立(H=60cm) ・ステップ (H=30cm)、 (共に前席とベットの間の隙間)
  14. 冷蔵庫(寝床下収納、15L、-5℃まで、12V/3.75A、45W)
  15. 電子レンジ (寝床下収納、AC100v/6A、出力400Wで家庭用レンジの1.5倍の時間をセット)
  16. 湯沸かし (0.8L、AC100V/6A) ・コーヒーセット (寝床用ボックス内収納)
  17. 非常食・ペットボトル・飲料水 (2L×4本、ギャレー家具内収納、篭で仕切って転倒防止)
  18. キッチン用品 (ギャレー家具内でマジックテープで固定した篭内などに収納)
  19. 給水ポット (シンク内でプラ篭にタオルで包んで押し込み、移動時の揺れを防止)
  20. パソコン・USB扇風機 (壁固定ラック内に収納)、スマホ(スマホスタンド)
  21. 折り畳みテーブル・椅子セット (LOGOS、後部シートと後部ドアの隙間に収納)
  22. 電気膝掛け (兼「掛け・敷毛布」、100V・45W、140×100cm、吊棚収納)。

    車工具・オーニングハンドル 外部電源ケーブル・工具 折り畳みテーブル
    炊飯器・紙食器・・ キッチン用品・非常食・・ 飲料水・歯磨き用品
    電子レンジ マルチシェード(百均収納袋) 湯沸かし・コーヒー・紙コップ
     

    ダッシュ照明
      夜(LEDライト点灯)

    収納ラック
    改造前(網)   改造後(縦・横書類ケース)


    2軸サーボ制御用カメラ台 ラズベリーパイ(25)〜OpenCVで顔認識&カメラ制御〜 シュピーレンの収納_etc