요약
한 개발자가 Rockchip RV1103 칩과 카메라 두 대로 리눅스가 도는 값싼 스테레오 비전 보드를 만들었습니다.
루트킷 랩스의 라이언 워커가 쓴 제작기입니다. 그는 1.1GHz 단일 코어에 램 64MB인 이 칩에 끌려, 아두이노 로봇에 장애물 회피용 깊이 정보를 주는 보드를 구상했습니다.
왜 중요한가
- 카메라 입력부터 깊이 계산까지 보드 하나가 처리하고, 결과를 시리얼로 내보냅니다.
- 그래서 리눅스를 돌리지 않는 마이크로컨트롤러 프로젝트에도 깊이 인식을 붙일 수 있습니다.
- 기판 설계 파일과 Buildroot 설정을 GitHub에 공개해 누구나 따라 만들거나 고칠 수 있습니다.
핵심 내용
- 깊이는 SAD(두 영상 조각의 픽셀 차이 절댓값을 더한 값) 블록 매칭으로 구하며, 이 연산은 칩의 영상 가속기가 맡습니다.
- 한 영상을 옆으로 밀며 맞춰 보는데, 많이 밀어야 맞는 부분일수록 가까운 물체입니다.
- 가속기는 제조사가 소스 없이 주는 라이브러리로만 다룰 수 있습니다.
- 첫 시제품에서는 칩을 잘못 주문하고 렌즈 마운트 구멍을 2.2mm가 아닌 1.8mm로 뚫는 실수가 있었습니다.
- 알림 신청이 20명을 넘으면 문제를 고친 보드 10개를 주문해 팔 계획이며, 가격은 밝히지 않았습니다.
HN 반응
- 일부 이용자는 글이 카메라 보정(렌즈 왜곡과 두 카메라의 위치 차이를 계산해 맞추는 작업)을 건너뛰었고, 데모도 보정 없이 돌린 것 같다고 지적했습니다.
- 기판이 몇 마이크로미터만 휘어도 보정이 틀어진다는 보충과, 용도와 두 카메라 간격 같은 정보가 빠졌다는 비판도 나왔습니다.
https://rootkitlabs.com/2023/07/08/5-Strategies-to-Sink-your-Hardware-Startup/ 그 블로그 글, 재미있게 읽었습니다.
이 글은 드롭쉬핑 성공담도, 큰돈을 번 엑시트 이야기도, 안내서도 아닙니다. 우리가 망한 하드웨어 스타트업을 기록한 어처구니없는 이야기입니다. 실패는 창피한 일이라 이런 이야기를 듣기는 쉽지 않은데, 제가 하나 들려드리겠습니다.
SAD 알고리즘이 깔끔해 보이네요!
시간은 얼마나 걸리나요? 오프셋 범위가 아주 넓지 않을까요? 아니면 최소 거리를 제한하면 그런 문제가 줄어드나요?
규칙적인 무늬가 있는 물체가 실제보다 멀리 있는 것으로 잘못 해석되는 예외 상황도 있을 것 같은데요?
SAD는 일반 데스크톱 CPU에서는 실시간보다 빠르게 돌아갑니다. 라즈베리 파이에서도 마찬가지입니다. 글쓴이는 스테레오에 필요한 보정(calibration) 과정을 거의 전부 얼버무리고 넘어갔습니다. 카메라 두 대를 달고 매처를 돌리면 끝나는 간단한 일이 아닙니다.
스테레오 시차(시차 disparity, parallax)는 거리에 반비례하기 때문에 넓은 범위를 탐색할 필요가 없습니다. 보정된 스테레오 시스템에서는 무한대에 있는 점의 시차가 0이어야 합니다. 그래서 보통은 깊이 범위를 정하고 거기에 해당하는 픽셀만 탐색합니다. 카메라가 보정되어 있으면 가로 방향으로만 탐색하면 되니 픽셀당 연산이 64번 정도로 줄고, CPU가 지원하면 벡터화도 할 수 있습니다. 다른 방식으로는 센서스(census, 매칭 윈도 안의 각 픽셀이 중심 픽셀보다 밝은지 비교)처럼 더 안정적인 비교를 쓰고 해밍 거리를 계산하는 것도 있는데, 이것도 매우 효율적입니다.
그리고 맞습니다, 스테레오는 반복되는 질감에 취약합니다. 하지만 텍스처가 아예 없는 빈 벽 같은 경우가 보통 더 나쁩니다.
저는 이 사람이 보정을 제대로 했는지 의심스럽습니다. 적어도 데모 영상은 상태가 꽤 안 좋아 보여요.
보정 없이 원본 이미지를 그대로(rectify 안 하고) 돌린 것 같습니다.
직접 해보고 싶은 분은 OpenCV에 이 주제를 다루는 튜토리얼이 여럿 있으니 보세요. stereoBM 같은 걸 쓰는데, 제 기억이 맞다면 이것도 SAD를 씁니다.
첫 단계는 보정입니다. 내부 파라미터(intrinsics, 렌즈 왜곡을 상쇄하는 식을 구하는 것)와 외부 파라미터(extrinsics, 두 카메라가 XYZ 방향으로 얼마나 떨어져 있고 기울기는 어떤지 등)를 구해야 합니다.
상수를 직접 조절해서 이미지가 정렬돼 보일 때까지 맞추는 식으로 할 수는 없을까요? 예전에 이 작업을 OpenCV로 해봤을 때는 k 값을 자동으로 계산해 주는 게 영 신통치 않았거든요. 언젠가 보정 없이도 시차를 구할 수 있는 알고리즘이 나오면 좋겠네요 :)
저는 실패한 프로젝트 하나에서 Vive Flow로 찍은 1초 간격의 mp4 스크린샷을, Gemini로 바이브코딩한 파이썬 cv2 스크립트에 넣어 봤는데 그 부분은 잘 되는 것 같았습니다. 다만 그 카메라는 SLAM용으로 설계하고 검증한 스테레오 카메라였고, 이미지 한 장을 쓸 수 있으려면 보드 전체가 선명하게 보여야 한다는 조건이 있긴 했어요. 잘 안 된다면 사각형 개수를 줄이고 조명을 조정해 보세요.
그런데 K가 스케일 계수 맞죠? 다른 파라미터가 괜찮다면 스케일만 문제일 때는 센서 크기와 초점 거리로 계산할 수도 있을 것 같습니다.
이럴 땐 SfM(structure from motion)을 쓰면 됩니다. 돌아다니면서 영상을 찍으세요. 드론 사진측량이 동작하는 방식, 즉 번들 조정(bundle adjustment)과 같습니다. 적어도 내부 파라미터는 구할 수 있습니다.
다만 고해상도 센서에서는 PCB가 살짝 휘기만 해도 보정이 무효가 됩니다. 픽셀 하나가 엉뚱한 자리로 가는 데는 몇 마이크로미터면 충분하거든요.
OpenCV가 이 작업을 간단하게 만들어 준다고까지는 못 하겠지만, findChessboardCorners, CharucoDetector, stereoCalibrate 같은 함수를 제공하고 인쇄용 보정 패턴을 만드는 코드까지 있습니다.
요즘은 LLM에게 이 함수들을 이어 붙이게 시킬 수도 있고요.
IR 필터를 떼고 IR 노이즈 프로젝터를 추가하면 도움이 될 수도 있습니다.
특히 가로 방향 탐색만 하려는 경우에는 신경 쓸 문제가 정말 많습니다.
센서를 단단하게 고정해야 합니다
센서를 두 축으로 기계적으로 보정해야 합니다
센서 사이에 있는 모든 재료의 열팽창계수도 따져야 합니다
제가 알기로 좋은 스테레오 시스템은 대부분 카메라를 묵직한 합금 덩어리에 고정해 둡니다.
멋지네요. 아주 잘 만들었어요. 저한테 쓸 데가 있으면 좋겠네요, 있다면 당장 하나 가져갈 텐데요.
일반적인 결론을 내리기 전에 두 번째 플랫폼에서 만든 것도 보면 좋겠습니다.
멋지네요! BOM 비용은 얼마인가요?
... 스테레오 기선 거리(baseline)랑 클럭 신호 분배의 어려움에 대한 얘기는 왜 하나도 없죠?
그리고 그냥 PS5 카메라를 사면 안 되나요? 제 기억으로는 PS5부터 일반 USB 단자로 바꿨고, PS4 카메라용 어댑터도 나와 있을 텐데요.
오픈소스나 오픈 하드웨어 프로젝트를 볼 때마다 그런 질문을 하시나요?
보통은 분명한 용도와 동기가 있습니다. 예를 들어 AR 패스스루 고글을 만드는데 기존 카메라는 너무 크다거나, 거기에 USB3 카메라는 쓰기 싫다거나 하는 식이죠. 이 글쓴이의 경우에는 그게 무엇인지 분명하지 않고, 프로젝트의 복잡도에 비해 글에 담긴 정보도 빈약합니다.