Depthカメラの評価と応用

2022年技術ブログ集

Depthカメラの評価と応用その1

Intel Realsense Depth Camera (D435i)の評価

DLサイト https://www.intelrealsense.com/get-started-depth-camera/

Intel Realsense Camera(D400シリーズ)のPythonライブラリ

RealSence D435をPythonで使う【画角を合わせる編】(Windows10) - Qiita
#お詫び半年くらい全く更新がありませんでしたが飽きたわけではなくてあるイベントのロボット製作が忙しく更新できていませんでした。VAEとかもほったらかしですし単眼カメラのSLAMとかもやりたいな…

IntelからD400シリーズのライブラリ「pyrealsense2」が提供されていて、pythonでの
プログラム開発を容易に行うことができます。

(ライブラリの導入)
 難しい設定説明が多数ありますがWindowsの場合は以下のpipだけでインストールできます。
 OSはWindows10(64bit)限定のようです。   $pip install pyrealsense2

(Depthカメラの初期設定)

import pyrealsense2 as rs
import numpy as np
import cv2

config = rs.config()
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
pipeline = rs.pipeline()
profile = pipeline.start(config)

(Depthカメラのリアルタイム(ループ)処理)

Depthカメラの評価と応用その2

RealSense D435iで3Dスキャナもどきの実装 – Qiita

RealSense D435iで3Dスキャナもどきの実装 - Qiita
Depthカメラで3Dスキャナもどきの実装(Open3Dの探索をかねて。)前回に続いてRealSense D435iで遊んでいきます。概要D435iでRGBDデータを作成するRGBDデータか…

上記URLのコードをそのまま動かしてみました。
3Dデータを.plyファイルに保存するプログラムです。

import pyrealsense2 as rs
import numpy as np
import open3d as o3d

ストリーム(Depth/Color)の設定

config = rs.config()
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)

ストリーミング開始

pipeline = rs.pipeline()
profile = pipeline.start(config)

Alignオブジェクト生成

align_to = rs.stream.color
align = rs.align(align_to)
try:
while True:
# フレーム待ち(Color & Depth)
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
color_frame = aligned_frames.get_color_frame()
depth_frame = aligned_frames.get_depth_frame()
if not depth_frame or not color_frame:
continue
color_image = o3d.geometry.Image(np.asanyarray(color_frame.get_data()))
depth_image = o3d.geometry.Image(np.asanyarray(depth_frame.get_data()))
rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(color_image, depth_image);
pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image,

o3d.camera.PinholeCameraIntrinsic(o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault))
# 回転する
pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
# 法線計算
pcd.estimate_normals()
# 指定したvoxelサイズでダウンサンプリング
voxel_down_pcd = pcd.voxel_down_sample(voxel_size=0.01)
distances = voxel_down_pcd.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
radius = 1.5 * avg_dist
# メッシュ化
radii = [radius, radius * 2]
mesh = o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(voxel_down_pcd,
o3d.utility.DoubleVector(radii))
# 再度法線計算
mesh.compute_vertex_normals()
# 一応データ保存
o3d.io.write_triangle_mesh(“output.ply”, mesh)
# メッシュデータの表示
o3d.visualization.draw_geometries([mesh])
finally:
# ストリーミング停止
pipeline.stop()

出力ファイルは「output.ply」に保存されます。

xxx.plyファイルはWindows10ではペイント3Dや3DビューアーやPrint3Dで開くことが
できました。

全てのソフトで視点を変えてみることもできます。

Print3Dでは3Dプリンタ用のファイルを生成できるようですが、データ生成時に
途中でエラーとなりました。完全な3Dデータになってないことが原因と考えられます。

Depthカメラの評価と応用その3

RGBカメラとDepthカメラの座標ずれ問題

RealSence D435をPythonで使う【画角を合わせる編】(Windows10) - Qiita
#お詫び半年くらい全く更新がありませんでしたが飽きたわけではなくてあるイベントのロボット製作が忙しく更新できていませんでした。VAEとかもほったらかしですし単眼カメラのSLAMとかもやりたいな…

D435iのRGB画像とDepth 画像は位置ずれしているようです。
ずれを補正するプログラムが上記URLに記載されていましたので追試しました。

ずれ補正前のRGB画像とDepth画像の表示プログラム

import pyrealsense2 as rs
import numpy as np
import cv2

config = rs.config()
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
pipeline = rs.pipeline()
profile = pipeline.start(config)
try:
while True:
frames = pipeline.wait_for_frames()
#RGB
RGB_frame = frames.get_color_frame()
RGB_image = np.asanyarray(RGB_frame.get_data())
#depyh
depth_frame = frames.get_depth_frame()
depth_image = np.asanyarray(depth_frame.get_data())
depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.08), cv2.COLORMAP_JET)

    images = np.hstack((RGB_image, depth_colormap))
    cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
    cv2.imshow('RealSense', images)
    if cv2.waitKey(1) & 0xff == 27:#ESCで終了
        cv2.destroyAllWindows()
        break

finally:
pipeline.stop()

ずれ補正後(赤色の部分が補正コード)のRGB画像とDepth画像の表示プログラム

import pyrealsense2 as rs
import numpy as np
import cv2

config = rs.config()
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
pipeline = rs.pipeline()
profile = pipeline.start(config)
align_to = rs.stream.color
align = rs.align(align_to)
try:
while True:
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
color_frame = aligned_frames.get_color_frame()
depth_frame = aligned_frames.get_depth_frame()
if not depth_frame or not color_frame:
continue
color_image = np.asanyarray(color_frame.get_data())
depth_image = np.asanyarray(depth_frame.get_data())
depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_image, alpha=0.08), cv2.COLORMAP_JET)
color_image_s = cv2.resize(color_image, (640, 480))
depth_colormap_s = cv2.resize(depth_colormap, (640, 480))
images = np.hstack((color_image_s, depth_colormap_s))
cv2.namedWindow(‘RealSense’, cv2.WINDOW_AUTOSIZE)
cv2.imshow(‘RealSense’, images)
if cv2.waitKey(1) & 0xff == 27:#ESCで終了
cv2.destroyAllWindows()
break
finally:
pipeline.stop()

画角補正はできているようです。
しかし、iphoneのケーブルが二重に映っています。距離が短いためか?

Depthカメラの評価と応用その4

Depth制限による不要な背景を取り除く処理

インテル Realsence D435iで、近くに来た物体だけを撮影してみました | DevelopersIO

初めて応用と呼べる例題が出てきました。AIで画像の学習データを
収集する際に拝啓を削除したいことがあります。
今回、Depthカメラを使って深さ制限をかけ背景を除去する検討を行いました。
上記のURLを参考にしました。

import pyrealsense2 as rs
import numpy as np
import cv2
WIDTH = 640;HEIGHT = 480
config = rs.config()
config.enable_stream(rs.stream.color, WIDTH, HEIGHT, rs.format.bgr8, 30)
config.enable_stream(rs.stream.depth, WIDTH, HEIGHT, rs.format.z16, 30)
pipeline = rs.pipeline()
profile = pipeline.start(config)
距離[m] = depth * depth_scale

depth_sensor = profile.get_device().first_depth_sensor()
depth_scale = depth_sensor.get_depth_scale()
clipping_distance_in_meters = 0.4 # 40cm以内を検出
clipping_distance = clipping_distance_in_meters / depth_scale
align_to = rs.stream.color
align = rs.align(align_to)
threshold = (WIDTH * HEIGHT * 3) * 0.95
try:
while True:
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)
color_frame = aligned_frames.get_color_frame()
depth_frame = aligned_frames.get_depth_frame()
if not depth_frame or not color_frame:
continue
color_image = np.asanyarray(color_frame.get_data())
depth_image = np.asanyarray(depth_frame.get_data())
white_color = 255 # 背景色
depth_image_3d = np.dstack((depth_image, depth_image, depth_image))
bg_removed = np.where((depth_image_3d > clipping_distance) | (depth_image_3d <= 0), white_color, color_image)
white_pic = np.sum(bg_removed == 255)

if(threshold > white_pic):
print(“検出 {}”.format(white_pic))
else:
print(“{}”.format(white_pic))
images = np.hstack((bg_removed, color_image))
cv2.imshow(‘Frames’, images)
if cv2.waitKey(1) & 0xff == 27:
break
finally:
pipeline.stop()
cv2.destroyAllWindows()

背景除去実験結果

背景削除追加実験

表面凹凸の少ないサツマイモを使用ました。輪郭線や部分的色抜は改善が見られましたが輪郭線は滑らかではありません。一方、カメラやメジャーの同一平面上にある文字は正確によみとれています。

Depthカメラの評価と応用その5

ポイントクラウド抽出とレンダリング処
https://qiita.com/idev_jp/items/0f71cf831b604f8adcea
事前準備としてOpen3Dライブラリを導入します。Open3Dの概要を以下にまとめます。

Open3Dライブラリによるrgbdデータの処理
参考サイト http://www.open3d.org/docs/release/getting_started.html

(ライブラリの導入)

以下の様にpipだけでインストールできます。
    $pip install open3d
注意)Numpyとの相性があるようでNumpyの再インストールが必要な場合があります。

import pyrealsense2 as rs
import numpy as np
import cv2
from open3d import *

if name==”main“:
align = rs.align(rs.stream.color)
config = rs.config()
config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 6)
config.enable_stream(rs.stream.color, 1280, 720, rs.format.rgb8, 6)
pipeline = rs.pipeline()
profile = pipeline.start(config)
# get camera intrinsics
intr = profile.get_stream(rs.stream.color).as_video_stream_profile().get_intrinsics()
print(intr.width, intr.height, intr.fx, intr.fy, intr.ppx, intr.ppy)
pinhole_camera_intrinsic = open3d.camera.PinholeCameraIntrinsic(intr.width, intr.height, intr.fx, intr.fy, intr.ppx, intr.ppy)
while True:
frames = pipeline.wait_for_frames()
aligned_frames = align.process(frames)

    color_frame = aligned_frames.get_color_frame()
    color_image = np.asanyarray(color_frame.get_data())

    cv2.namedWindow('color_image', cv2.WINDOW_AUTOSIZE)
    cv2.imshow('color_image', cv2.cvtColor(color_image, cv2.COLOR_RGB2BGR))
    if cv2.waitKey(1) != -1:
        print('finish')
        break

 depth_frame = aligned_frames.get_depth_frame()
depth = open3d.geometry.Image(np.asanyarray(depth_frame.get_data()))
color = open3d.geometry.Image(color_image)
#rgbd = create_rgbd_image_from_color_and_depth(color, depth, convert_rgb_to_intensity = False);
rgbd = open3d.geometry.RGBDImage.create_from_color_and_depth(color,depth)
#pcd = create_point_cloud_from_rgbd_image(rgbd, pinhole_camera_intrinsic)
pcd = open3d.geometry.PointCloud.create_from_rgbd_image(rgbd,pinhole_camera_intrinsic)
pcd.transform([[1,0,0,0],[0,-1,0,0],[0,0,-1,0],[0,0,0,1]])

pipeline.stop()
open3d.io.write_point_cloud('avocado.pcd', pcd,True)
open3d.visualization.draw_geometries([pcd])

PointCloudデータの抽出とVexcelによる3Dレンダリング処理

Depthカメラの評価と応用その6

Depth Camera(D435i/D405)の深度評価

2021年末にIntelから工業用Derpthカメラ(D405)が発売されました・
早速入手してD435iとの評価を行いました。

Depth Camera(D435i/D405)の測定限界深度評価

D405の下方深度測定可能領域は、5.5cm~であり、D435iは、16.5cm~ であることが判りました。

Depth Camera(D435i/D405)の深度分解能評価

Depthカメラの評価と応用その7

D405を使った表面状態測定システムの開発
深さ分解能が非常に高いD405を使って表面の凹凸を測定するシステムを製作しました。

Depthデータの断面切り出しプログラムの追加

D405Depth画像取得GUIプログラム:D405VideoCapture2

Depthデータの解析プログラム:3D_roughness

Depthデータ処理のまとめ

表面ラフネス測定表示GUIプログラムD405GUI.py

机の表面

ノートの表面

Al板の表面

金属表面は乱反射の影響があり正確なラフネスの測定が困難だと思われる。

ランチョンマットの表面

布表面のしわを検出しているものと思われます。

Depthカメラの評価と応用その8

アボカド表皮ラフネスの経時変化の観察

D405を使った表面凹凸変化測定システム

アボカド画像の経時変化(購入から11日間同じ個所を測定)

測定プログラム

経時変化データ

表面段差とばらつきの経時変化グラフ

D405を応用して表面状態や、表面状態の変化を観察しました。
もう少し有効な応用例を今後も探していこうと思います。

タイトルとURLをコピーしました