みらいテックラボ

音声・画像認識や機械学習など, 管理人が興味のある技術の紹介や実際にトライしてみた様子などメモしていく.

ピープルカウンタを考えてみる(3)

Code for Naraがらみで, 施設に出入りする人のカウント及びそのデータ分析などの実証実験を, とある場所(ヒ・ミ・ツ!!)の施設管理者に提案しようという話が持ち上がっている.

前回, Intel Real Sense D415を入手し, Linux上での開発環境構築を紹介したが, 2-3日後D415がお亡くなりになり, Depth画像が取得できなくなってしまった.
結局初期不良ということで, 昨日やっとD415を再入手することができた.
今回は, D415からDepth画像入力を行い, 初回に紹介したPeople Counterで処理してみた.


関連記事:
ピーブルカウンタを考えてみる(1)
ピープルカウンタを考えてみる(2)
・ピープルカウンタを考えてみる(3)
ピープルカウンタを考えてみる(4)
ピープルカウンタを考えてみる(5)


3. Depthカメラ(2)
3. 3 Depth画像入力
People Counterと接続することを考え, Intel RealSense SDK2.0[1]python wrapperを使用して, pythonでDepth画像を取得できるようにした.

SDK内のサンプルコード(opencv_viewer_example.py)を参考にコード実装したが, ポイントは以下の2つ.

  • People Counterでグレースケール画像に変換して背景除去など行うので, Depth画像を入力の段階でグレースケール画像とした.
  • 背景等は不要なので, 今回は2m以上の距離のものは表示しないようにした.

[コード]

# -*- coding: utf-8 -*-

#############################################
##      D415 Depth画像の表示&キャプチャ
#############################################
import pyrealsense2 as rs
import numpy as np
import cv2

TARGET_DISTANCE = 2.0 # meter
OUTPUT_VIDEO_FILE = 'sample_depth.avi'

# Configure depth and color streams
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)

# ストリーミング開始
profile = pipeline.start(config)

# Depthスケール取得
#   距離[m] = depth * depth_scale 
depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
# 対象範囲の閾値
distance_max = TARGET_DISTANCE/depth_scale
print('Depth Scale = {} -> {}'.format(depth_scale, distance_max))

# Output file
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
out = cv2.VideoWriter(OUTPUT_VIDEO_FILE, fourcc, 24, (640, 480))

if out.isOpened() == False:
    print('File {0} open error.'.format(OUTPUT_VIDEO_FILE))
    exit()

try:
    while True:
        # フレーム待ち(Depth & Color)
        frames = pipeline.wait_for_frames()
        depth_frame = frames.get_depth_frame()
        color_frame = frames.get_color_frame()
        if not depth_frame or not color_frame:
            continue
        color_image = np.asanyarray(color_frame.get_data())
        # Depth画像前処理(2m以内を画像化)
        depth_image = np.asanyarray(depth_frame.get_data())
        depth_image = (depth_image < distance_max) * depth_image
        depth_graymap = depth_image * 255. / distance_max
        depth_graymap = depth_graymap.reshape((480, 640)).astype(np.uint8)
        depth_colormap = cv2.cvtColor(depth_graymap, cv2.COLOR_GRAY2BGR)

        # 入力画像表示
        images = np.hstack((color_image, depth_colormap))
        cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('RealSense', images)
        out.write(depth_colormap)
        if cv2.waitKey(1) & 0xff == 27:
            break

finally:
    # ストリーミング停止
    pipeline.stop()
    cv2.destroyAllWindows()


3. 4 予備実験
本来, 天井にDepthカメラを設置することを想定しているが, USBケーブルが短かったので, 人の往来で試してみることにした.
人の往来をカウントするために, 上下方向から左右方向の移動をカウントするようにPeople Counterを修正し, Depth画像を処理させてみた.

[予備実験結果]

people counter

Depth画像は動画からもわかるように, RGB画像と比較すると, かなりちらつきがある.
当初サンプルコードにあるようにDepth画像をカラーマップ化して処理すると, 背景除去や人物領域の検出がうまくできなかった.
そこで, 入力段階でDepth画像をグレースケール画像にし, また, 不要な背景部分を距離でカットするようにしたことで, 一応人の往来をカウントできるようになった.

今後は, 天井位置に配置したDepthカメラで人の往来を撮影して, People Counterの画像処理の処理結果やカウント性能などを確認する必要がある..

----
参照URL:
[1] GitHub - IntelRealSense/librealsense: Intel RealSense SDK




ディジタル画像処理[改訂新版]

ディジタル画像処理[改訂新版]


ディジタル画像処理の基礎と応用―基本概念から顔画像認識まで (ディジタル信号処理シリーズ)

ディジタル画像処理の基礎と応用―基本概念から顔画像認識まで (ディジタル信号処理シリーズ)


画像認識 (機械学習プロフェッショナルシリーズ)

画像認識 (機械学習プロフェッショナルシリーズ)


OpenCVによる画像処理入門 改訂第2版 (KS情報科学専門書)

OpenCVによる画像処理入門 改訂第2版 (KS情報科学専門書)