Optical Tactile Sensing · DIGIT / GelSight

The Sensor That
Doesn't See Color

DIGIT의 RGB는 색이 아니라, 빛으로 인코딩된 표면 기울기다

DIGIT·GelSight 계열 센서의 RGB 값은 물체의 반사색이 아니다. 내부 RGB LED가 만든 음영(shading) 패턴이며, 이로부터 접촉면의 surface normaldepth를 복원하기 위한 중간 표현이다.

01 / 핵심

RGB 카메라가 아니라, "기울기 추정기"다

일반 RGB 카메라는 물체가 어떤 색인지를 측정한다. 빨간 사과는 빨갛게 찍힌다. 하지만 DIGIT는 다르다. 카메라 앞에 투명한 젤(gel)과 불투명 코팅이 있고, 그 안에서 RGB LED가 비춘다. 그래서 카메라가 보는 것은 물체의 색이 아니라 젤 표면이 빛을 반사한 음영이다.

투명 젤 (gel) + 불투명 반사막 R G B LED 내부에서 비춤 카메라 막의 음영만 본다 (색 ✕)
DIGIT 촉각센서 (개념도) · 카메라는 물체가 아니라, 내부 RGB LED가 비춘 젤·막의 음영을 본다
"DIGIT의 RGB ≈ 물체의 색"이 아니라 → "RGB ≈ 젤 표면의 기울기(normal)와 변형(deformation)"

그래서 빨간 사과를 눌러도 빨갛게 찍히지 않는다. 색 정보는 사실상 버려지고, 거의 회색 imprint에 가까운 음영만 남는다. 중요한 것은 color가 아니라 contact geometry다.

02 / 비교

일반 카메라 vs DIGIT

일반 RGB 카메라DIGIT
RGB = 물체의 반사색RGB = LED 조명에 의한 음영(shading)
빨간 사과는 빨갛게 보임빨간 사과도 거의 회색 imprint
색상(color) 정보가 핵심형상(geometry) 정보가 핵심
Texture 인식Contact geometry 인식
03 / 원리

왜 하필 "기울기"로 바뀌는가

한 줄 결론부터. DIGIT의 RGB가 변하는 이유는 물체의 색이 변해서가 아니라, 눌린 막(membrane)의 기울기가 각 LED 빛의 반사 밝기를 바꾸기 때문이다. 그 밝기와 기울기를 잇는 법칙이 Lambert 코사인 법칙이다. 아래 네 단계로 풀면 "갑자기 왜 기울기?"가 사라진다.

먼저 내부 구조와 접촉 시 흐름:

내부 적층 구조
Object
Gel (투명 탄성체)
Reflective Membrane
RGB LED
Camera
접촉 시 일어나는 일
평평한 막
↓ 변형
표면 법선(기울기) 변화
↓ Lambert
LED별 반사 밝기 변화
카메라 RGB 변화
1

카메라는 물체가 아니라 "막"을 본다

젤 위에는 불투명한 반사막이 코팅돼 있다. 빛은 물체까지 가지 않고 이 막에서 반사돼 카메라로 돌아온다. 막이 자기 반사 특성(BRDF)을 갖기 때문에, 물체가 빨갛든 투명하든 광택이 있든 측정되는 건 오직 막의 모양이다. (Li et al., CVPR 2013)

2

막은 물체 형상대로 눌려 들어간다

물체가 누르면 막이 접촉면 형상 그대로 변형된다. 곧 막의 3D 형상 = 접촉면의 형상이다. 평평하던 막의 각 지점이 저마다 다른 방향, 즉 다른 법선(surface normal)으로 기운다. 이 "지점별 기울기"가 이후 모든 정보의 원천이다.

3

매트한 면은 "광원을 향한 정도"만큼 밝게 반사한다 — Lambert 코사인

여기서 기울기가 등장한다. 막은 매트(Lambertian)해서, 한 LED의 빛을 받아 카메라로 되돌리는 밝기는 면의 법선이 그 LED 방향과 이루는 각 θcos에 비례한다. 면이 LED를 정면으로 향하면(θ=0) 가장 밝고, 옆으로 기울수록 어두워지며, 스치는 각(θ=90°)이면 0이 된다. 식으로는 I = I₀·cos θ = I₀·(n·s). (Lambert 코사인 법칙)

LED θ≈0° 정면 cos θ≈1.0 · 최대 LED θ 기울어짐 cos 45°≈0.71 · 절반 LED θ 거의 스침 cos 78°≈0.21 · 약함
같은 LED · 같은 빛 — 면이 광원을 정면으로 향할수록(θ↓) 반사 밝기↑. 노란 화살표=법선 n, 점선=광원 방향, 막대=반사 밝기
4

색이 다른 LED 3개 → 세 방향에서 기울기를 잰다 → 법선을 푼다

왼쪽 R, 오른쪽 G, 위쪽 B처럼 서로 다른 방향에 색 LED를 둔다. 그러면 한 픽셀의 R·G·B는 같은 면(같은 법선 하나)을 세 방향에서 잰 밝기, 곧 세 개의 cos 값이다. 비공면 광원 3개면 이 셋을 연립해 그 픽셀의 법선 1개를 유일하게 풀 수 있다(photometric stereo). 즉 LED가 3개인 건 법선이 3개라서가 아니라, 법선 하나를 풀기 위한 측정이 3개 필요하기 때문이다. 그래서 RGB ≈ surface normal. 실제 GelSight도 공을 눌러 RGB→법선 룩업테이블을 보정한다. (Dong et al., 2017 · Woodham 1980)

θ=0° · 정면 → 최대 θ=45° → 절반 θ=90° · 스침 → 0 30° 60° 90° 면이 LED 방향에서 기울어진 각 θ 반사 밝기 (R 채널) I = I₀ · cos θ = I₀ · (n · s)
한 채널의 밝기 = 면 기울기 각 θ의 cos · 색이 아니라 "기울기"가 밝기를 정한다

한 가지 덧붙이면, 이 곡선이 보여주듯 밝기는 기본적으로 cos을 따라 매끄럽게 줄어든다. 그래서 RGB가 어딘가에서 급격히 점프(꺾임)하는 건 일반 법칙이 아니라, 물체에 모서리(edge)가 있어 법선이 한 픽셀 사이에서 급변하는 특수한 지점일 뿐이다. 평평하거나 완만한 곡면에서는 RGB도 부드럽게 변한다.

광원(빛) 1개일 때 s (광원 방향) θ 면 위 한 점 원뿔 위 어느 법선이든 cos θ 동일 → 밝기 동일 측정 1개 = 원뿔 1개 한 점으로 안 좁혀짐
빛 1개 → 법선은 이 원뿔(iso-brightness cone) 위 어딘가일 뿐 · 측정 1개로는 한 점으로 못 좁힌다
면(픽셀) 1개 · 법선 n 1개 R LED G LED B LED n 측정값 3개 (한 픽셀) R = n · s_R G = n · s_G B = n · s_B ↓ 연립 법선 n : 단 1개로 결정
광원 3개 = 법선 3개가 아니다 · R·G·B는 같은 법선 n 하나를 비추는 세 개의 단서
헷갈리기 쉬운 점 · 법선은 1개, 측정이 3개

LED가 3개여도 면마다 진짜 법선은 하나뿐이다. 빛 하나로 잰 밝기 한 개만으로는 "어느 방향으로 기울었는지"가 모호하다(같은 밝기를 주는 기울기가 원뿔처럼 무수히 많다). 서로 다른 방향의 빛 3개로 재면 그 모호함이 사라지고 기울기가 하나로 정해진다 — GPS가 위성 3개의 거리로 내 위치 한 점을 찍는 것과 같다. 그래서 위 "표면을 기울이면 RGB가 바뀐다" 그림처럼 법선이 1개인 게 맞고, R·G·B는 그 하나의 법선을 비추는 3개의 단서다.

정리하면, RGB 값은 색이 아니라 다음을 암호화(encode)한 값이다.

R,G,B  ≈  surface normal  ≈  surface gradient  ≈  depth
04 / 직접 해보기

표면을 기울이면 RGB가 바뀐다

LED 배치를 왼쪽=Red, 오른쪽=Green, 위쪽=Blue로 가정하자. 아래 패드에서 점을 끌어 표면 normal(법선)의 방향을 바꿔보면, 그 면을 향하는 LED 채널이 강해진다. 평평할 때(중앙)는 R=G=B로 거의 회색이다.

◀ RED GREEN ▶ ▲ BLUE
drag · 표면 법선 방향을 끌어보세요
n
CAMERA가 보는 RGB
rgb()
R
0
G
0
B
0
구(球)를 눌렀을 때의 imprint
왜 무지개처럼 보일까? 구를 누르면 표면의 각 지점마다 normal 방향이 다르다. 왼쪽 면은 R, 오른쪽 면은 G, 위쪽 면은 B가 강해진다. 그래서 단순한 회색 공이 아니라, 방향별로 색이 갈리는 그라데이션 blob으로 찍힌다 — 이것이 바로 "RGB = surface normal 코드"의 증거다.
05 / 복원 파이프라인

RGB → Normal → Depth

RGB는 시작점일 뿐, 목표는 depth map이다. 그래서 calibration / depth reconstruction 연구는 RGB를 그대로 쓰지 않고 거의 항상 아래 3단계를 거친다. 핵심은 가운데 단계 — RGB가 주는 건 "높이"가 아니라 점마다의 "기울기"라서, 마지막에 그 기울기를 적분해야 비로소 높이가 나온다는 점이다.

RGB              Surface Normal   (① 학습된 매핑 / 룩업)
Surface Normal   Gradient Field   (② 점마다 경사 p,q)
Gradient Field   Depth Map        (③ Poisson 적분)
1

RGB → Normal · 색을 법선으로 디코딩

각 픽셀의 (R, G, B)를 그 지점의 표면 법선 n=(nx, ny, nz)로 바꾼다. 앞에서 봤듯 RGB는 법선을 부호화한 값이라, 이 변환은 룩업테이블이나 작은 신경망으로 학습한다. 보정은 보통 반지름을 아는 공을 누르는 방식이다. 공 표면은 점마다 법선이 수학적으로 정확히 알려져 있어서, "이 RGB ↔ 이 법선" 대응표를 자동으로 채울 수 있다.

2

Normal = 기울기장 · 아직 "높이"가 아니다

법선은 그 점에서 면이 "얼마나, 어느 쪽으로 기울었는지"만 알려준다. 즉 픽셀마다 국소 경사 (p, q) = (∂z/∂x, ∂z/∂y)를 얻는다. 하지만 경사만으로는 그 지점의 절대 높이는 모른다 — 산비탈의 경사를 점마다 알아도, 그것만으로 해발고도가 바로 나오지 않는 것과 같다.

3

Normal → Depth · 기울기를 적분한다 (Poisson)

높이 z(x,y)를 얻으려면 이 경사들을 이어 붙여(적분) 쌓아 올려야 한다. 단순히 한 줄로 더해 나가면 경로마다 결과가 달라지고 노이즈가 누적된다. 그래서 Poisson solver를 쓴다 — 측정된 경사장과 가장 잘 맞는(최소제곱) 단 하나의 높이지도를 전역적으로 푼다(∇²z = div(gradient)). 이 결과가 곧 depth map이다.

① 측정값 : 점마다의 기울기 (normal) ↓ 기울기를 적분 (Poisson) ↓ ② 복원 결과 : 높이 z(x) = depth
기울기(경사)는 "방향과 가파름"만 준다 · 그걸 이어 붙여(적분) 올라가야 실제 높이 곡선이 된다 (1D 비유)
왜 단순 합산이 아니라 Poisson인가

측정한 경사에는 노이즈가 섞여 있어, 한 경로로만 더해 올라가면 시작점·진행 방향에 따라 높이가 달라지고 오차가 한쪽으로 쌓인다. Poisson 방식은 "모든 픽셀의 경사를 동시에 가장 잘 만족하는" 높이지도를 한 번에 푸는 최소제곱 적분이라, 경로에 무관하고 노이즈가 평균화된다. 그래서 결과가 매끄럽고 일관된 depth map이 된다.

실제 DIGIT depth 복원 코드(예: vocdex/digit-depth)도 이 구조 그대로다 — RGB → Normal 네트워크를 학습한 뒤, Poisson 적분으로 normal을 depth로 바꾼다.

06 / 센서 편차

같은 구를 눌러도 RGB가 다르다

RGB 절대값은 센서마다 다르다. 똑같은 물체(같은 형상)를 눌러도 개체별로 R·G·B 숫자가 어긋난다. 중요한 건 그 차이의 원인이 물체가 아니라 센서 하드웨어에 있다는 점이다. 즉 형상은 같은데 "색 좌표"만 틀어진 것이라, calibration이 풀어야 할 문제의 성격이 달라진다.

DIGIT #1

R=120  G=90  B=70

DIGIT #2 · 같은 물체

R=105  G=110  B=85
같은 물체 · 같은 형상 RGB는 다름 DIGIT #1 R120 G90 B70 DIGIT #2 R105 G110 B85 보정 #1 · RGB→normal 보정 #2 · RGB→normal = 동일한 normal / depth
같은 형상 → 센서마다 RGB는 갈리지만(≠), 각자의 보정을 거치면 같은 normal/depth로 수렴(=) · 불변량은 색이 아니라 형상

같은 형상인데도 RGB가 갈리는 이유는 photometric 방정식의 상수들이 개체마다 다르기 때문이다. 앞서 본 I = I₀·(n·s)에서, 물체가 정하는 건 n뿐이고 나머지(I₀, s, 카메라 응답)는 전부 센서가 정한다.

  • LED 밝기 차이 · 위치 오차 — 광원 세기 I₀와 방향 s가 바뀐다. 같은 법선이라도 측정 밝기가 통째로 달라진다.
  • 카메라 white balance · 게인 — 같은 빛도 다른 RGB 숫자로 기록된다(색 축이 회전·스케일).
  • gel 두께 · reflective coating 편차 — 막의 반사 특성(BRDF)과 빛 감쇠가 달라진다.
  • 내부 광학 왜곡 — 위치별로 밝기·색이 불균일해져 같은 법선도 화면 위치마다 다르게 찍힌다.
그래서 calibration의 목표가 바뀐다

목표는 "센서들의 RGB를 똑같이 맞추는 것"이 아니라, "RGB가 달라도 같은 depth/normal이 나오게 만드는 것"이다. 두 가지 방향이 있다. ① 센서마다 RGB→normal 매핑을 따로 보정한다(공 누르기로 그 개체의 대응표를 새로 만든다). ② 학습 단계에서 LED 밝기·색·왜곡을 일부러 흔드는 도메인 랜덤화로, RGB 변동에 둔감하고 형상에만 반응하는 모델을 만든다. 어느 쪽이든 불변량은 색이 아니라 형상이다.

실제 사례 · PyTouch (Lambeta et al., ICRA 2021)

이 "센서 편차" 문제를 실제로 다룬 대표 라이브러리가 PyTouch다. raw RGB를 직접 만지는 대신 touch 여부·미끄럼(slip)·물체 자세 같은 작업 단위 추상화로 묶어, DIGIT·OmniTact·GelSight를 같은 인터페이스로 처리한다. 논문은 같은 DIGIT라도 제조 편차와 image transfer layer 차이 때문에 개체마다 다르게 찍힌다는 점을 명시하고, 그 변형들을 가로질러 동작하도록 모델 일반화를 다룬다. 특히 여러 센서로 함께 학습한 모델이 단일 센서 모델보다 성능이 좋다고 보고하는데, 이는 위 ②(센서를 가로지르는 형상 중심 학습) 전략을 실증한 결과다. 다만 PyTouch는 이런 상위 작업 추상화에 초점을 둔 라이브러리라, 앞 절의 RGB→normal→depth 같은 저수준 기하 복원(예: Poisson 적분)은 digit-depth나 3D Cal 같은 도구가 담당한다.

07 / 연구 관점

원시 데이터는 RGB가 아니라 normal map이다

로봇 학습 입장에서 DIGIT의 "진짜 입력"은 색이 아니라 형상이다. 그래서 raw 데이터를 rgb_image가 아니라 surface_normal_map(또는 depth)으로 보는 게 더 직관적이다. 실제로 많은 최신 연구는 RGB를 모델에 직접 넣지 않고, 먼저 형상 표현으로 바꾼 뒤 그것만 저장·학습한다.

# 색(RGB)은 저장하지 않는다 — 형상만 남긴다
depth_map            # 접촉면의 높이 z(x,y)
normal_map           # 점마다의 기울기 n
marker_displacement  # 막 위 마커의 이동 → 힘/전단

이렇게 하는 이유는 세 가지다.

  • 센서 독립성 — 06에서 봤듯 RGB는 개체마다 다르지만, normal/depth는 같은 형상이면 같다. 형상으로 바꿔 저장하면 센서가 바뀌어도 학습이 깨지지 않는다.
  • 다운스트림 정렬 — 파지·삽입·미끄럼 감지 같은 작업이 실제로 필요로 하는 건 "접촉면이 어떻게 생겼나(형상)"와 "힘이 어디로 작용하나"다. 색은 그 작업에 쓰이지 않는 잉여 정보다.
  • 표현 압축 — RGB 3채널을 형상·접촉량으로 요약하면, 정책 학습이 다뤄야 할 입력이 작고 의미가 또렷해진다.
① 접촉 전 규칙적인 격자 (정지) ② 수직으로 누름 바깥으로 퍼짐 → 법선력 ③ 옆으로 밀림 한쪽으로 쏠림 → 전단·미끄럼
막에 찍힌 격자 점(marker)의 이동 패턴이 힘을 알려준다 · 회색=원래 위치, 노랑=눌린 뒤 위치
marker_displacement = 형상이 아니라 "힘"을 읽는 채널

막에는 두 정보가 같이 담긴다. 형상은 RGB 음영 → normal → depth로 읽고("무엇이 닿았나"의 모양), 은 막에 일부러 찍어둔 격자 점(marker)으로 읽는다. 접촉 전 점들은 규칙적인 격자로 가만히 있다가, 누르면 따라 움직인다. 이 점들의 이동(displacement field)이 힘의 단서다 — 점들이 바깥으로 퍼지면 수직으로 누르는 힘(법선력), 한쪽으로 쏠리면 옆으로 미는 힘(전단력), 그게 갑자기 죽 미끄러지면 slip이다. 핵심은 같은 막에서 두 채널을 다른 신호로 읽는다는 점 — 형상은 음영에서, 힘은 마커 이동에서. 물체 모양이 똑같아도 살살 vs 꾹, 똑바로 vs 비스듬히에 따라 마커 일그러짐이 달라지므로, 형상만으로는 안 보이는 "얼마나 세게·어느 쪽으로"가 마커에 드러난다.

비유 · 매트리스에 손을 대면

푹신한 매트리스에 손바닥을 댄다고 하자. 매트리스가 파인 모양은 손의 형상(= normal/depth)이고, 매트리스에 그려둔 체크무늬가 어떻게 일그러졌는지는 손이 가한 힘의 방향·세기(= marker displacement)다. 같은 손이라도 살살 vs 꾹, 똑바로 vs 비스듬히에 따라 무늬 일그러짐이 달라진다. 참고로 모든 DIGIT가 마커를 쓰는 건 아니다 — 마커가 있으면 힘·전단을 잘 읽지만 형상 디테일을 가려서, 마커 없는 센서는 형상에, 마커 있는 센서는 힘·미끄럼에 강한 트레이드오프가 있다.

한 발 더 나가면, "raw를 무엇으로 볼 것인가"에는 사실 두 가지 흐름이 있다. 위에서 본 방식은 RGB를 normal·depth·marker처럼 사람이 정의한 물리량으로 명시적으로 분해(handcrafted)하는 것이다 — 해석이 명확하고 보정도 직관적이다. 최근에는 여기에 더해, RGB를 명시적 기하로 풀기 전에 학습된 표현(latent representation)으로 바꾸는 흐름이 강해지고 있다.

최근 흐름 · 학습된 touch 표현 (Sparsh, 2024)

전통적으로 촉각 처리는 marker tracking·FEM·dense normal estimation 같은 전처리로 접촉 속성을 직접 뽑아 왔다(이 자료의 앞 절이 그 갈래다). Sparsh는 다른 길을 택한다 — 라벨 없이 46만 장 이상의 촉각 이미지로 self-supervised 사전학습(MAE·DINO·JEPA)해, DIGIT·GelSight 등을 가로지르는 범용 touch 표현을 만든다. 힘·미끄럼처럼 라벨 수집이 비싸고 어려운 속성에 특히 유리하다. 벤치마크(TacBench 6개 작업)에서 작업·센서별 end-to-end 학습 대비 평균 95.1% 향상을 보고했고, 특히 latent 공간 학습(DINO·IJEPA)이 가장 강했다. 정리하면, raw RGB의 종착지는 둘 중 하나다 — 명시적 형상(normal/depth)이거나, 학습된 표현(latent)이거나. 어느 쪽이든 "색 자체"가 목적이 아니라는 점은 같다.

결론 / 한 문장

한 문장으로 정리하면

한 문장 정의

DIGIT의 RGB 값은 물체의 색상이 아니라, 내부 RGB LED 조명이 만든 shading pattern이며, 이 패턴으로부터 접촉면의 surface normal과 depth를 복원하기 위한 중간 표현이다.

즉 "RGB는 물체의 색이라기보다, 형상의 깊이를 추정하기 위한 빛의 산란을 담은 정보"라는 직관은 정확하다.