本日は AzureKinect と Blender の調査枠です。
AzureKinect から取得したカラー画像とデプス画像を使って Blender で立体を再構築してみます
前回記事の続きです。
bluebirdofoz.hatenablog.com
今回はノイズ部分の削除を行います。
モディファイアの反映
今回の処理は頂点に対して直接変更を行うため、モディファイアを予め適用しておきます。
モディファイアの適用は不可逆的な作業となるため、作業前にプロジェクトを保存しておく事をお奨めします。
各モディファイアの[適用]ボタンをクリックしてモディファイアを適用します。
このとき、[サブディビジョンサーフェス]->[ディスプレイス]の順で適用するように注意します。
逆の順序で適用すると、モディファイアの順序が変わるため、形状が変化してしまいます。
デプスの欠落を削除する
最初にデプスの欠落箇所の頂点を削除します。
デプスの欠落箇所は深度が 0.00 で出力されているため、Y:0.00 の位置に頂点が配置されています。
マージンを取って Y:0.20 未満の箇所の頂点を全て削除しました。
以下のスクリプトを作成して利用しました。
・Remove_noise_lack.py
import bpy
import bmesh
def remove_noise_lack(arg_objectname='Default'):
selectob = bpy.data.objects[arg_objectname]
bpy.context.view_layer.objects.active = selectob
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
if selectob.mode == 'EDIT':
meshdata = bmesh.from_edit_mesh(selectob.data)
bpy.ops.mesh.select_all(action='DESELECT')
for vert in meshdata.verts:
if vert.co.y < 0.2:
vert.select_set(True)
bpy.ops.mesh.delete(type='VERT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete_loose()
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
return
remove_noise_lack('Plane')
削除後のメッシュが以下になります。
大きな欠落部分は削除されましたが、まだ多くのノイズがあります。
ノイズ部分をスムーズにする
小さなノイズまで削除してしまうとメッシュに大量の穴が発生するので、頂点のスムーズ化をかけて形を整えることにしました。
メッシュの面積が極端に大きい箇所を検出してスムーズ化を実行します。
以下のスクリプトを作成して利用しました。
・Smooth_noise_point.py
import bpy
import bmesh
def smooth_noise_points(arg_objectname='Default'):
selectob = bpy.data.objects[arg_objectname]
bpy.context.view_layer.objects.active = selectob
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
if selectob.mode == 'EDIT':
meshdata = bmesh.from_edit_mesh(selectob.data)
meshdata.verts.ensure_lookup_table()
bpy.ops.mesh.select_all(action='DESELECT')
objdata = bpy.context.object.data
for poly in objdata.polygons:
if poly.area > 0.0004:
print(poly.area)
for vindex in poly.vertices:
meshdata.verts[vindex].select_set(True)
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
bpy.ops.mesh.select_less()
bpy.ops.mesh.vertices_smooth(factor=1.0, repeat=30, xaxis=False, yaxis=True, zaxis=False)
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
return
smooth_noise_points('Plane')
ノイズ部分がスムーズ化されて形が見えてきました。
更にノイズを除去する
それでも残っているノイズを除去するなら、更にもう一度クリーンアップや不要な面の削除を行います。
ただし、あまりやり過ぎると正しい計測部分も削除してしまうため、選択範囲の設定などを調整しつつ実施します。
・Remove_noise_point.py
import bpy
import bmesh
def remove_noise_points(arg_objectname='Default'):
selectob = bpy.data.objects[arg_objectname]
bpy.context.view_layer.objects.active = selectob
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
if selectob.mode == 'EDIT':
meshdata = bmesh.from_edit_mesh(selectob.data)
meshdata.verts.ensure_lookup_table()
bpy.ops.mesh.select_all(action='DESELECT')
objdata = bpy.context.object.data
for poly in objdata.polygons:
if poly.area > 0.0004:
print(poly.area)
for vindex in poly.vertices:
meshdata.verts[vindex].select_set(True)
bpy.ops.mesh.delete(type='VERT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.delete_loose()
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
return
remove_noise_points('Plane')
これでノイズの除去が完了しました。
3Dモデルを正しく再現するため、次回は最後に画角の補正を実施します。
bluebirdofoz.hatenablog.com