Upgrade to Pro — share decks privately, control downloads, hide ads and more …

スケッチから3Dモデルを検索してみた / Searching 3D models from ...

スケッチから3Dモデルを検索してみた / Searching 3D models from sketches

Masaki Inaba

August 29, 2022
Tweet

Other Decks in Technology

Transcript

  1. 自己紹介 • Masaki Inaba | @mi_spindel ◦ お気軽にメッセージください • 某光学機器メーカでマシン/ロボットビジョン

    某自動車部品メーカで自動運転/運転支援向けの車載画像認識 某AIスタートアップで様々な受託AI開発 • 2022/7/1にキャディ株式会社に入社しました AI Labで2D/3D図面の認識・検索技術の開発に関わっています 2
  2. CADSketchNet, DatasetA • Mechanical Components Benchmark: MCB, ECCV2020がベース ◦ 58,696スケッチ(.png),

    58,696モデル(.obj), 68クラス • コンピュータにより生成されたスケッチ(computer-generated sketch: cgs) ◦ 視線は20方向から機械工学で設計を学んだ学生に投票で一つに決めてもらったとのこと ◦ (なぜ1視点しか作らなかったのだろう…) 8
  3. • Engineering Shape Benchmark: ESB, Computer-Aided Design2006がベース ◦ 800スケッチ(.png), 866モデル(.obj),

    42クラス • 手書きスケッチ(hand) ◦ 視線はDatasetAと同様に決めて、学生に手書きスケッチを描いてもらった ◦ (800か…少ないな…) CADSketchNet, DatasetB 9
  4. CADSketchNet, Experiment • 何か色々書いてあるけど、(Multi-view) CNN, Siamese-Networkの構成で DatasetA, BともにTop k-Accurasyは90%を超えるとのこと •

    ただ、DatasetA内で学習・評価、DatasetB内で学習・評価した実験結果しかなく、 コンピュータ生成スケッチで学習し手書きスケッチを評価したものが気になる 10
  5. 実際にやってみた • やったこと ◦ CNN(スケッチ) - Multi-view CNN(3Dモデル)によるSiamese-Network ▪ PyTorch3DによるMulti-view

    Rendering ◦ DatasetA(コンピュータ生成スケッチ)による学習⇒DatasetB(手書きスケッチ)の評価 ◦ DatasetB(コンピュータ生成スケッチ)による学習⇒DatasetB(手書きスケッチ)の評価 • やらないこと ◦ CADSketchNetの再現実験 ▪ 公開コードも無く、実験条件の詳細も不明確なので無理。。。 ▪ https://github.com/bharadwaj-manda/CADSketchNet ◦ 検索精度の追及 README only 11
  6. マルチビューレンダリングをする • Multi-view Convolutional Neural Networks for 3D Shape Recognition,

    ICCV2015では”Blender”を使ってるけど、せっかくなので”PyTorch3D”を試用 ◦ 今回はパラメタ固定なので意味ないですが、微分可能(のはず) ◦ 参考: PyTorch3Dチュートリアル, MVTN: Multi-View Transformation Network for 3D Shape Recognition, ICCV2021のコード • レンダリング時のパラメタはMVCNNの条件を参考にする 13
  7. PyTorch3Dによるマルチビューレンダリングコード例1 class MultiViewRenderer(nn.Module): def forward(self, meshes, azim, elev, dist): background_color

    = torch.tensor((1.0, 1.0, 1.0)) color = torch.tensor((1.0, 1.0, 1.0)) lights = DirectionalLights(direction = (0, 1.0, 0)) rendered_images, cameras = self.render_meshes( meshes=meshes, color=color, azim=azim, elev=elev, dist=dist, lights=lights, background_color=background_color) return rendered_images, cameras meshes: batch_size * [Pytorch3D.Mesh] azim: (batch_size, nb_views) elev: (batch_size, nb_views) dist: (batch_size, nb_views) rendered_images: (batch_size*nb_views, 3, width, height) 背景色 物体色 y方向無限遠にある点光源 Mathworks 方位角と仰角の視点の設定より 14
  8. def render_meshes(self, meshes, color, azim, elev, dist, lights, background_color=(1.0, 1.0,

    1.0)): c_batch_size = len(meshes) verts = [msh.verts_list()[0].cuda() for msh in meshes] faces = [msh.faces_list()[0].cuda() for msh in meshes] for i in range(len(verts)): verts[i] = verts[i] - torch.mean(verts[i], 0) # weighted mean based on face area is better mgn = 1.0 / torch.max(torch.max(verts[i], 0).values - torch.min(verts[i], 0).values) verts[i] = verts[i] * mgn new_meshes = Meshes( verts=verts, faces=faces, textures=None) max_vert = new_meshes.verts_padded().shape[1] new_meshes.textures = Textures( verts_rgb=color.cuda()*torch.ones((c_batch_size, max_vert, 3)).cuda()) R, T = look_at_view_transform(dist=batch_tensor(dist.T, dim=1, squeeze=True), elev=batch_tensor(elev.T, dim=1, squeeze=True), azim=batch_tensor(azim.T, dim=1, squeeze=True)) cameras = FoVPerspectiveCameras(device=meshes.device, R=R, T=T) PyTorch3Dによるマルチビューレンダリングコード例2 中心位置正規化 サイズ正規化 (タスクに依存) テクスチャを設定 元objにはテクスチャがない カメラ位置姿勢を設定 batch_size*nb_views 15
  9. raster_settings = RasterizationSettings( image_size=self.image_size, # 224 blur_radius=0.0, bin_size = 0,

    faces_per_pixel=self.faces_per_pixel, # 1 cull_backfaces=self.cull_backfaces # False ) renderer = MeshRenderer( rasterizer=MeshRasterizer( cameras=cameras, raster_settings=raster_settings ), shader=SoftPhongShader( blend_params=BlendParams(background_color=background_color), device=meshes.device, cameras=cameras, lights=lights ) ) new_meshes = new_meshes.extend(self.nb_views) rendered_images = renderer(new_meshes, cameras=cameras, lights=lights) rendered_images = rendered_images[..., 0:3].transpose(1, 3).transpose(2, 3) return rendered_images, cameras PyTorch3Dによるマルチビューレンダリングコード例3 ラスタライズ設定 ポリゴンから画素生成 Phongの反射モデル メッシュをnb_viewsの数 コピーしてレンダリング alphaチャンネル削除 16
  10. レンダリング実行 from pytorch3d.io import load_objs_as_meshes nb_views = 12 obj_path="test.obj" mvr

    = MultiViewRenderer(nb_views=nb_views) elev = torch.stack([torch.linspace(30, 30, nb_views)]) azim = torch.stack([torch.linspace(-180, 180-360/nb_views, nb_views)]) dist = torch.stack([torch.Tensor([2.0]*nb_views)]) meshes = load_objs_as_meshes(obj_path).cuda() images, cameras = mvr.forward(meshes, azim, elev, dist) MVCNNと同様の12視点 17
  11. モデル • CNN-MVCNNのSiamese Network風 ResNet18 ResNet18 ResNet18 ResNet18 ResNet18 …

    View max pooling Linear LeakyReLU Linear LeakyReLU 128次元 128次元 18
  12. その他、学習条件など • Dataset: DatasetA_cgs, DatasetB_cgs, DatasetB_hand ◦ クラスインバランス対策にWeightedRandomSampler • Optimizer:

    Adam, Learning Rate = 1.0e-4 • Batch Size: 8 • LeakyReLU negative slope = 0.01 • Data Augmentation ◦ スケッチのみHorizontal / Vertical Flip • 評価 ◦ Top-k Accuracy 各クラスのデータ数 左: DatasetA, 右: DatasetB 19
  13. まとめ • スケッチからの3Dモデル検索をやってみた過程を紹介しました ◦ CADSketchNetのデータセットを利用し、 CNN-MVCNNのSiamese Network構成で実際にやってみた ▪ PyTorch3Dによるマルチビューレンダリングの方法も紹介 ◦

    結果、コンピュータ生成のスケッチではそれなりに上手くいった ◦ ただ、ナイーブにコンピュータ生成のスケッチを学習したモデルで リアルな手書きのスケッチをクエリとして扱うのは難しいことが分かった • データ拡張、手書き風変換、Domain Adaptationあたりを 頑張ると変わるかもしれない • 手書きスケッチを描く側に制約を入れるのも大事だと思う ◦ 視点位置姿勢の固定、Draw Strokeの補正など 24