画像処理とコンピューター ビジョンの世界では、RGBD は画像内の色情報と深度情報を組み合わせるデータ形式を指します。このテキストでは、Python を使用して RGBD データを 3D 点群に変換する方法を紹介しています。NSDT 3DConvert を使用して、3D 点群をオンラインで表示したり、形式変換を実行したりできます。
1. RGBD = カラー + 深度
RGB という略語は 3 つの原色チャネルを表し、各チャネルは 0 ~ 255 の整数値で表されます。これらの値は、対応する色の強度を決定します。0 は色なしを示し、255 は最大強度を示します。最初の値は赤のチャネルを表し、2 番目の値は緑を表し、3 番目の値は青を表します。RGB 値が増加すると、色の特性はその特定のカラー チャネルに向かって収束します。これを説明するために、次の例を考えてみましょう。
(RGB) -> color
(0, 0, 0) -> black
(255, 0, 0) -> red
(0, 255, 0) -> green
(0, 0, 255) -> blue
(255, 255, 255) -> white
頭字語 RGBD の最後の文字は深度チャネルを表します。この値は、画像の距離情報を提供します。深度値は、飛行時間型 (ToF) センサー、構造化光センサー、ステレオ カメラのセットアップなど、さまざまな手法を通じて取得できます。これらのセンサーは、光または電磁波がセンサーから物体に到達して戻ってくるまでにかかる時間を測定することによって深度値を計算します。
2. 3D点群
3D 点群は、3 次元デカルト座標系の一連のデータ ポイントで構成される基本的なデータ構造です。雲内の個々の点は、x、y、および座標によって正確に定義される 3D 空間内の固有の位置に対応します。 z 座標。点群は、コンピューター ビジョン、ロボット工学、地理情報システム (GIS)、3D モデリングなど、さまざまなソフトウェア業界の主要なエンティティです。
3. RGBD画像から3D点群を作成
2D 画像から 3D 点群を作成するには、焦点距離と基点の知識が重要です。この目的のために、カメラ行列が入力として与えられます。
以下のブロックは、標準的なピンホール カメラのカメラ マトリックスを示しています。
| fx 0 cx |
Camera Matrix = | 0 fy cy |
| 0 0 1 |
各パラメータの意味は次のとおりです。
- fx: x 軸に沿った焦点距離を表します。
- fy: y 軸に沿った焦点距離を表します。
- cx: 基点の x 座標を表します。これは、x 軸に沿った画像平面の中心です。
- cy: 基点の y 座標を表します。これは、y 軸に沿った画像平面の中心です。
知らせ:
- 右下隅の要素はスケール係数を表し、通常は 1 に設定されます。
- 他の要素は、水平 (x) 軸と垂直 (y) 軸の間の歪みや傾きの影響を伴うことなく、カメラの透視投影を示します。
- RGBD 2D 画像と標準ピンホール カメラのカメラ マトリックスが提供されると、基本的な数学原理を使用して 3D 点群を構築できます。
上図によると、f (焦点距離) はカメラ行列で与えられ、y (ピクセルの y 座標) はピクセルを列挙することで計算でき、z (深度) は深度値です。3D 点群を作成するには、Y を計算する必要があります。三角形の相似性を使用すると、Y = y * z / f となります。ここではy座標についてのみ説明しますが、x座標も同様の計算式で求めることができます。
次の関数は上記の手順を実装します。
def to_3D(fx, fy, depth, cx, cy, u, v):
x = (u-cx)*depth/fx
y = (v-cy)*depth/fy
z = depth
x = np.expand_dims(x, axis = -1)
y = np.expand_dims(y, axis = -1)
z = np.expand_dims(z, axis = -1)
return np.concatenate((x,y,z), axis=-1)
上記の関数では、u パラメーターと v パラメーターはピクセルの xy 座標を表します。これらのパラメーターを説明するために、640 ピクセル列と 480 ピクセル行の画像を使用して値が作成された次のデータを考えてみましょう。
the shape of u = (480, 640)
the shape of v = (480, 640)
u =
[[ 0 1 2 ... 637 638 639]
[ 0 1 2 ... 637 638 639]
[ 0 1 2 ... 637 638 639]
...
[ 0 1 2 ... 637 638 639]
[ 0 1 2 ... 637 638 639]
[ 0 1 2 ... 637 638 639]]
v =
[[ 0 0 0 ... 0 0 0]
[ 1 1 1 ... 1 1 1]
[ 2 2 2 ... 2 2 2]
...
[477 477 477 ... 477 477 477]
[478 478 478 ... 478 478 478]
[479 479 479 ... 479 479 479]]
最後に、次の関数を使用して 3D 点群を作成できます。
def make_point_cloud(datapath, fx, fy, cx, cy):
rgbd = .....\load data
H = len(rgbd)
W = len(rgbd[0])
u = np.arange(W)
v = np.arange(H)
u, v = np.meshgrid(u, v)
xyz = to_3D(fx, fy, rgbd[:,:,3], cx, cy, u, v)
rgb = rgbd[:,:,:-1]
point_cloud = np.concatenate((xyz, rgb), axis=-1)
return point_cloud
4. RGBDから3D点群への変換例
入力RGB画像と深度画像は以下のとおりです。
左: RGB 画像 右: 深度画像
前の関数を使用すると、取得する 3D 点群は次のようになります。
元のリンク: RGBD 画像から 3D 点群へ — BimAnt