aidense-modelsrobot-perception6d-pose-estimationmanipulationdeep-learningdondensefusiondensematcher

Mô hình Dense trong Robotics: Từ DON đến DenseMatcher

Khám phá Dense Object Nets, DenseFusion và DenseMatcher — bộ ba công nghệ dense visual descriptor đang cách mạng hóa cách robot nhìn và cầm nắm vật thể.

Nguyễn Anh Tuấn22 tháng 4, 202613 phút đọc
Mô hình Dense trong Robotics: Từ DON đến DenseMatcher

Hãy tưởng tượng bạn yêu cầu một robot cầm lấy đúng cái tai phải của một con thú nhồi bông hình sâu bướm. Không phải tai trái, không phải thân, mà đúng cái tai phải. Robot chưa bao giờ nhìn thấy con sâu bướm này trước đây.

Nghe như khoa học viễn tưởng? Không — đây là kết quả thực tế của một nghiên cứu từ MIT CSAIL năm 2018, và nó được thực hiện nhờ một khái niệm gọi là mô hình Dense (Dense Models) trong robotics.

Bài viết này sẽ đưa bạn từ nền tảng lý thuyết đến code thực tế, đi qua ba công trình quan trọng nhất trong lĩnh vực dense visual representation cho robot: Dense Object Nets (DON), DenseFusion, và DenseMatcher.


Dense là gì? Tại sao lại quan trọng?

Trước khi vào chi tiết, hãy hiểu rõ "dense" nghĩa là gì trong ngữ cảnh này.

Trong computer vision, có hai cách tiếp cận chính:

Sparse (thưa): Trích xuất một số ít điểm đặc trưng nổi bật từ ảnh — ví dụ như góc cạnh, cạnh, hoặc keypoint theo kiểu SIFT/ORB. Nhanh, nhưng bỏ qua nhiều thông tin.

Dense (dày đặc): Tính toán một đặc trưng (feature vector) cho mỗi pixel trong ảnh. Chậm hơn, tốn tài nguyên hơn, nhưng cực kỳ phong phú về thông tin.

Sparse: [  *   ,    *  ,  *   ,     *    ]
         keypoint keypoint ...

Dense:  [p₁, p₂, p₃, ..., pₙ]  ← mỗi pixel có một feature vector

Với robot, dense representation mở ra những khả năng không thể làm được với sparse:

  • Nhận dạng điểm cụ thể trên vật thể: "Cầm vào đây, không phải chỗ kia"
  • Generalize sang vật thể chưa thấy: Học từ một con giày → cầm được mọi đôi giày
  • Robust với partial occlusion: Vẫn hoạt động khi vật thể bị che một phần
  • Không cần CAD model: Không cần bản vẽ kỹ thuật của vật thể

Dense Object Nets (DON) — Nền tảng của mọi thứ

Paper: Dense Object Nets: Learning Dense Visual Object Descriptors By and For Robotic Manipulation
Tác giả: Peter R. Florence, Lucas Manuelli, Russ Tedrake — MIT CSAIL
Hội nghị: CoRL 2018 (Best Paper Award)
GitHub: RobotLocomotion/pytorch-dense-correspondence

Ý tưởng cốt lõi

DON học một hàm ánh xạ: mỗi pixel (u, v) trong ảnh → một vector đặc trưng D ∈ ℝᵈ (thường d = 3 hoặc d = 16).

Các vector này được học sao cho:

  • Cùng điểm trên vật thể → vector gần nhau trong không gian đặc trưng
  • Điểm khác nhau → vector xa nhau

Điều kỳ diệu: vector này không phụ thuộc vào góc nhìn. Nghĩa là cái tai phải của con sâu bướm sẽ luôn có cùng vector đặc trưng dù bạn nhìn nó từ phía trước, bên hông, hay từ trên xuống.

Kiến trúc DON

RGB Image (H×W×3)
      │
      ▼
  FCN Backbone (ResNet-34 hoặc VGG-16)
      │
      ▼
  Dense Feature Map (H×W×D)
  ← mỗi pixel có D-dimensional descriptor

DON dùng Fully Convolutional Network (FCN) — không có fully connected layers, nên output giữ nguyên kích thước spatial với ảnh input.

Training: Self-supervised với RGB-D

Điều thú vị nhất về DON là nó hoàn toàn self-supervised — không cần nhãn thủ công. Training data được tạo tự động từ camera RGB-D:

1. Chụp nhiều ảnh vật thể từ nhiều góc độ
2. Dùng depth + camera pose để project điểm 3D
3. Tự tạo correspondence: pixel A trong ảnh 1 ↔ pixel B trong ảnh 2 
   (cùng điểm 3D trên vật thể)
4. Train với contrastive loss

Contrastive Loss:

# Match loss: descriptor của matching pair phải gần nhau
L_match = ||D(u_a) - D(u_b)||²

# Non-match loss: descriptor khác pair phải xa hơn margin M
L_non_match = max(0, M - ||D(u_a) - D(u_c)||)²

# Total loss
L = L_match + α * L_non_match

Ứng dụng thực tế: Robot grasping theo điểm

import torch
import numpy as np
from dense_correspondence.network.dense_correspondence_network import DenseCorrespondenceNetwork

# Load model đã train
dcn = DenseCorrespondenceNetwork.from_model_folder('path/to/trained_model')
dcn.eval()

# Ảnh reference: người dùng chỉ vào điểm cần cầm
img_ref = load_image('caterpillar_reference.png')  # H×W×3
target_pixel = (120, 85)  # pixel tay chỉ vào

# Lấy descriptor của điểm target
with torch.no_grad():
    descriptor_map_ref = dcn.forward_single_image(img_ref)
    target_descriptor = descriptor_map_ref[target_pixel[0], target_pixel[1]]  # D-dim vector

# Ảnh live từ camera robot
img_live = get_camera_frame()  # ảnh mới của vật thể (vị trí/góc khác)

# Tìm điểm tương ứng trong ảnh live
with torch.no_grad():
    descriptor_map_live = dcn.forward_single_image(img_live)
    
    # L2 distance với toàn bộ map
    diff = descriptor_map_live - target_descriptor  # H×W×D
    dist = torch.norm(diff, dim=-1)  # H×W
    
    # Best match
    best_pixel = torch.argmin(dist.view(-1))
    best_y = best_pixel // img_live.shape[1]
    best_x = best_pixel % img_live.shape[1]

print(f"Điểm cần cầm trong ảnh live: ({best_x}, {best_y})")

Kết quả DON

MIT thử nghiệm DON với cánh tay robot Kuka LBR iiwa:

  • Grasping accuracy: 87.4% success rate khi cầm đúng điểm chỉ định
  • Cross-instance: Học từ 1 chiếc giày → cầm được giày khác chưa từng thấy
  • Non-rigid objects: Hoạt động với vải, túi, đồ mềm

Dense visual descriptor map — mỗi màu đại diện cho một vị trí ngữ nghĩa trên vật thể


DenseFusion — 6D Pose Estimation với RGB-D Fusion

Paper: DenseFusion: 6D Object Pose Estimation by Iterative Dense Fusion
Tác giả: Chen Wang, Danfei Xu, Yuke Zhu, et al. — Stanford University
Hội nghị: CVPR 2019
GitHub: j96w/DenseFusion

Vấn đề: 6D Pose Estimation là gì?

Khi robot cầm một vật thể, nó cần biết chính xác:

  • Translation (3D): Vật thể đang ở đâu trong không gian (x, y, z)
  • Rotation (3D): Vật thể xoay theo hướng nào (roll, pitch, yaw)

Tổng cộng 6 bậc tự do — gọi là 6D pose.

Tại sao DON không đủ?

DON tốt cho việc tìm điểm tương ứng, nhưng để có 6D pose chính xác, ta cần:

  1. Kết hợp thông tin màu sắc (RGB) và độ sâu (Depth)
  2. Xử lý ở mức pixel (dense) thay vì sparse keypoints

DenseFusion làm điều này bằng cách fusion dense features từ cả RGB và point cloud.

Kiến trúc DenseFusion

RGB Image ──────────────────────► RGB Feature Extractor (PSPNet)
      │                                    │
      │                                    ▼ per-pixel color features
      │
Depth Image → Point Cloud ───────► PointNet Feature Extractor
                                           │
                                           ▼ per-point geometry features
                                    
                          [Fusion Layer: RGB + Geometry per point]
                                           │
                                           ▼
                             Pose Estimation Head
                             → (R, t) per object instance
                             → Confidence score per prediction

Điểm mấu chốt: DenseFusion không fusion ở global level — nó fusion tại mỗi điểm trong point cloud với pixel tương ứng trong ảnh RGB. Điều này giữ lại spatial information cực kỳ chi tiết.

Setup và chạy DenseFusion

# Cài đặt dependencies
conda create -n densefusion python=3.7
conda activate densefusion
pip install torch==1.7.1 torchvision==0.8.2
pip install scipy==1.2.0 opencv-python transforms3d

# Clone repo
git clone https://github.com/j96w/DenseFusion.git
cd DenseFusion

# Download YCB-Video dataset (training)
# Dataset: 80 training videos + synthetic data + 2949 test frames
wget https://rse-lab.cs.washington.edu/projects/posecnn/dataset.html
# (theo hướng dẫn trên trang chủ YCB-Video)

# Training trên YCB-Video dataset
python tools/train.py \
  --dataset ycb \
  --dataset_root path/to/YCB_Video_Dataset \
  --batch_size 8 \
  --workers 10 \
  --lr 0.0001 \
  --start_epoch 0

Iterative Refinement — Bước quan trọng thứ hai

DenseFusion không chỉ predict pose một lần — nó có thêm bước Iterative Refinement:

# Bước 1: Dự đoán pose ban đầu
initial_pose = densefusion_model(rgb, depth, roi)

# Bước 2: Refine lặp đi lặp lại
current_pose = initial_pose
for i in range(num_iterations):
    # Dùng pose hiện tại để transform point cloud
    transformed_cloud = transform_point_cloud(depth_cloud, current_pose)
    
    # Predict refinement (delta R, delta t)
    delta = refinement_model(rgb, transformed_cloud, roi)
    
    # Cập nhật pose
    current_pose = compose_pose(current_pose, delta)

final_pose = current_pose

Mỗi vòng lặp, pose được cải thiện dần dần — giống như bạn căn chỉnh một đồ vật cho đến khi vừa khớp.

Kết quả DenseFusion

Thử nghiệm trên YCB-VideoLineMOD datasets:

Metric DenseFusion (no refine) DenseFusion (iterative)
ADD(-S) AUC trên YCB 86.2% 91.8%
ADD trên LineMOD 79.7% 86.2%

So với các phương pháp trước đó (PoseCNN, DeepIM), DenseFusion cải thiện ~12-15% với thời gian inference nhanh hơn.


DenseMatcher — Generalize từ Một Demo

Paper: DenseMatcher: Learning 3D Semantic Correspondence for Category-Level Manipulation from a Single Demo
Tác giả: Junzhe Zhu et al. — TEA Lab
Hội nghị: ICLR 2025
GitHub: TEA-Lab/DenseMatcher
Project: https://tea-lab.github.io/DenseMatcher/

Vấn đề mới: Category-level generalization

DON và DenseFusion hoạt động tốt cho instance-level — tức là vật thể cụ thể mà robot đã thấy. Nhưng nếu muốn robot học từ một demo và áp dụng lên mọi loại cốc (dù khác hình dạng, kích thước), đó là category-level generalization — và đây là bài toán khó hơn nhiều.

DenseMatcher giải quyết bài toán này bằng cách học dense 3D correspondence giữa các vật thể trong cùng category.

DenseMatcher — học 3D correspondence từ multiview 2D features và functional maps

Kiến trúc DenseMatcher

Object Mesh A                          Object Mesh B
     │                                      │
     ▼                                      ▼
Multi-view Rendering                 Multi-view Rendering
(nhiều góc nhìn)                     (nhiều góc nhìn)
     │                                      │
     ▼                                      ▼
2D Foundation Model                  2D Foundation Model
(DINO / Stable Diffusion)            (DINO / Stable Diffusion)
     │                                      │
     ▼                                      ▼
Project features → Mesh Vertices     Project features → Mesh Vertices
     │                                      │
     ▼                                      ▼
3D GNN Refinement                    3D GNN Refinement
     │                                      │
     └──────────────────┬─────────────────┘
                        ▼
              Functional Map Layer
              (tìm correspondence function)
                        │
                        ▼
              Dense 3D Correspondence
              (mọi vertex A ↔ vertex B)

Bước 1 — Project 2D features lên 3D mesh:
Render vật thể từ nhiều góc (16-32 views), dùng DINO hoặc Stable Diffusion để trích xuất 2D features, sau đó project ngược lên mesh vertices theo weighted averaging.

Bước 2 — 3D GNN refinement:
Graph Neural Network chạy trên mesh graph để làm mượt và nhất quán hóa features, tận dụng cấu trúc 3D của vật thể.

Bước 3 — Functional Maps:
Thay vì tìm correspondence trực tiếp (cực kỳ tốn kém với mesh lớn), DenseMatcher dùng Functional Maps — biểu diễn correspondence dưới dạng ma trận ánh xạ giữa không gian spectral của hai mesh. Sau đó convert ngược về point-to-point correspondence.

Setup DenseMatcher

# Clone và setup
git clone https://github.com/TEA-Lab/DenseMatcher.git
cd DenseMatcher
conda create -n densematcher python=3.9
conda activate densematcher
pip install -r requirements.txt

# Download pre-trained model
python scripts/download_model.py

# Thử nghiệm với 2 object mesh
python demo.py \
  --mesh_a data/example/cup_A.obj \
  --mesh_b data/example/cup_B.obj \
  --output_dir results/

Áp dụng vào robot manipulation

from densematcher import DenseMatcher
import numpy as np

# Load model
matcher = DenseMatcher.from_pretrained('densematcher-v1')

# Demo: robot học cách cầm cốc A
# Grasp point trên cốc A (từ human demo)
demo_mesh = load_mesh('cup_A.obj')
demo_grasp_vertex = 1247  # index của vertex ở vị trí tay cầm

# Target: cốc B (chưa từng thấy, hình dạng khác)
target_mesh = load_mesh('cup_B.obj')

# Tìm correspondence
correspondence = matcher.compute_correspondence(demo_mesh, target_mesh)

# Tìm vertex tương ứng trên cốc B
target_grasp_vertex = correspondence[demo_grasp_vertex]
target_grasp_position = target_mesh.vertices[target_grasp_vertex]

print(f"Điểm cầm trên target cup: {target_grasp_position}")
# → Robot dùng điểm này để thực hiện grasp

Kết quả DenseMatcher

  • Outperforms baselines: +43.5% so với phương pháp 3D matching tốt nhất trước đó
  • Cross-category: Học từ cốc → cầm được bình nước, hộp, dù khác category
  • Long-horizon tasks: Thực hiện được chuỗi thao tác phức tạp (mở nắp → rót → đóng) chỉ từ 1 demo
  • Zero-shot: Không cần fine-tune cho vật thể mới

So sánh ba phương pháp

Tiêu chí DON (2018) DenseFusion (2019) DenseMatcher (2025)
Input RGB-D images RGB + Point Cloud 3D Mesh
Output 2D pixel descriptors 6D pose (R, t) 3D vertex correspondence
Generalization Cross-instance (rigid) Instance-level Category-level (cross-instance)
Supervision Self-supervised Fully supervised Self-supervised (via foundation models)
Foundation model Không Không Có (DINO, SD)
Real-time Có (~10ms) Có (~20ms) Không (offline)
Ứng dụng Grasping specific points Pick-and-place chính xác One-shot imitation learning

Pipeline thực tế cho robot manipulation

Trên thực tế, các hệ thống robot hiện đại kết hợp cả ba phương pháp:

Camera (RGB-D)
      │
      ├──► Segmentation (Mask R-CNN / SAM) → object ROI
      │
      ├──► DenseFusion ─────────────────────► 6D Pose (để plan trajectory)
      │
      └──► DON / DenseMatcher ───────────────► Grasp point (để xác định điểm cầm)
                                                      │
                                              Motion Planner
                                                      │
                                              Robot Execution

Pipeline kết hợp dense perception cho robot manipulation trong môi trường công nghiệp


Hướng phát triển tiếp theo

Sau DenseMatcher, nghiên cứu đang đi theo hướng:

1. Dense features từ Foundation Models:
DINOBot (2024) và các công trình tương tự dùng trực tiếp features từ DINO-ViT — không cần train thêm. Features này đã đủ "dense" và "semantic" để matching.

2. Dense World Models:
Thay vì predict pose rời rạc, predict toàn bộ scene representation dưới dạng dense feature map — cho phép planning dài hạn chính xác hơn.

3. 4D Dense Tracking:
Theo dõi dense correspondence qua thời gian (không chỉ spatial) — biết mỗi điểm trên vật thể đã di chuyển thế nào, thay đổi thế nào trong quá trình robot tương tác.

4. Kết hợp với VLA models:
Dùng dense visual features làm visual tokens cho Vision-Language-Action models, thay vì global image embedding — giúp model "nhìn" chi tiết hơn.


Cài đặt và thử nghiệm nhanh (DON)

Nếu bạn muốn bắt đầu với DON ngay hôm nay:

# Yêu cầu: Ubuntu 20.04+, CUDA 11+, Python 3.8+
git clone https://github.com/RobotLocomotion/pytorch-dense-correspondence.git
cd pytorch-dense-correspondence

# Cài dependencies
pip install torch torchvision
pip install -r requirements.txt

# Download pre-trained model (shoes dataset)
python scripts/download_models.py --model shoes

# Run demo: tìm correspondence giữa 2 ảnh
python scripts/find_correspondences.py \
  --model_path trained_models/shoes \
  --image_a data/shoes/image_a.png \
  --image_b data/shoes/image_b.png \
  --pixel_a 150 120  # pixel bạn quan tâm trong image A

Output: một ảnh với điểm tương ứng được vẽ trong image B — bạn có thể thấy ngay descriptor matching hoạt động thế nào.


Kết luận

Dense models đã thay đổi căn bản cách robot hiểu và tương tác với vật thể:

  • DON (2018) đặt nền móng: mỗi pixel có nghĩa, không phải chỉ toàn bộ ảnh
  • DenseFusion (2019) fusion RGB + Depth ở mức pixel → 6D pose chính xác
  • DenseMatcher (2025) tổng quát hóa lên category-level với foundation models

Xu hướng rõ ràng: dense representation ngày càng mạnh hơn khi kết hợp với foundation models (DINO, Stable Diffusion). Một robot năm 2026 không cần hàng ngàn demo — vài chục demo với dense matching đủ để generalize rộng.

Nếu bạn đang xây dựng hệ thống manipulation, đây là stack được khuyến nghị:

  1. Segmentation: SAM (Segment Anything Model) để tách object
  2. Pose: DenseFusion hoặc FoundationPose cho 6D pose
  3. Grasp point: DenseMatcher cho category-level generalization
  4. Policy: ACT hoặc Diffusion Policy cho motion planning

Bài viết liên quan

NT

Nguyễn Anh Tuấn

Robotics & AI Engineer. Building VnRobo — sharing knowledge about robot learning, VLA models, and automation.

Khám phá VnRobo

Bài viết liên quan

NEWDeep Dive
VLA-RFT: RL Fine-Tune VLA trong World Simulator
vlavla-rftreinforcement-learningworld-modelgrpoliberoopenhelixmanipulation

VLA-RFT: RL Fine-Tune VLA trong World Simulator

VLA-RFT dùng world model làm simulator để fine-tune VLA bằng GRPO, reward kiểm chứng và code GitHub trên LIBERO.

3/6/202614 phút đọc
NEWTutorial
Chạy Wall-OSS-0.5 với LeRobot
wall-ossvlalerobotmanipulationzero-shot

Chạy Wall-OSS-0.5 với LeRobot

Hướng dẫn chạy Wall-OSS-0.5, VLA 4B open-source zero-shot cho robot manipulation, từ paper đến LeRobot training và inference.

3/6/202613 phút đọc
NEWNghiên cứu
A1 VLA: Deploy VLA SOTA với Latency Giảm 72%
vlarobot-armfrankaagibotopen-sourceflow-matchinginference-optimizationmanipulation

A1 VLA: Deploy VLA SOTA với Latency Giảm 72%

Hướng dẫn A1 VLA open-source: giảm latency 72% trên Franka/AgiBot nhờ Inter-Layer Truncated Flow Matching, đạt SOTA trên LIBERO 96.6% và VLABench 53.5%.

1/6/202612 phút đọc