COMUTER VISION
무인 편의점 개발기 - Edge Device로 Object Tracking 시스템 구축하는 방법
2020-11-17
무인편의점 프로젝트는 ‘비전(vision) 기술을 활용해 일상에서 쉽게 접할 수 있는 제품’을 만들어보자는 취지로 시작됐습니다. 여러 아이디어 중 자사가 지난 수년간 축적해온 내부 기술을 조합한 “여러 카메라를 이용한 사람 추적 시스템”이 무인편의점이라는 컨셉에 가장 부합한다고 판단, 지난 2019년 9월부터 개발을 진행하고 있습니다.
현재 카카오엔터프라이즈의 사내 공간인 ‘비전룸’은 무인편의점 형태로 운영되고 있습니다. 곳곳에 설치된 여러 대의 카메라가 비전룸에 입장한 사람들의 행동(공간 내 어디에 있는지, 어떤 상품을 집었는지 등)을 실시간으로 추적합니다.
AI Lab이 구성한 사람 추적 시스템은 크게 4가지 모듈로 구성돼 있습니다.
- 먼저 추적 대상을 찾는 person detector
- 대상의 관절 위치를 찾는 pose estimator
- 매장 내 사람의 위치를 추정하는 multi-view geometry
- 영상에서 사람의 위치를 실시간 추적하는 person tracker
카메라 촬영으로 획득한 영상 데이터는 사실 매우 고용량의 데이터라 서버로 전송해 이를 분석하려면 많은 시간과 비용이 듭니다. 이를 해결하고자 AI Lab은 여러 카메라에서 획득한 영상을 한 대의 엣지 디바이스로 분석할 수 있도록 하는 시스템 구축에 집중했습니다.
이 개발 프로젝트를 공동 리드한 카카오엔터프라이즈・카카오 소속 엔지니어인 김한샘(person detection), 강동오(pose estimation), 박민호(multi-view geometry), 안지운(person tracking), 임현호(system integration)를 만나 사람 추적 시스템의 구조를 자세히 들어봤습니다.
∙ ∙ ∙ ∙ ∙ ∙ ∙
무인 편의점 ‘비전룸’
먼저, 저희가 만든 가상의 편의점은 이렇습니다. 실험을 위해 사내에 ‘비전룸’이라는 공간을 설치했고요. 이 방의 중앙에는 과자, 라면 등이 있는 매대와, 구석에는 냉동 또는 냉장 식품을 넣을 수 있는 매대가 설치되어 있습니다.
그리고 이 공간에서 일어나는 일을 저희의 비전 기술로 파악하기 위해 총 8대의 카메라를 사방에 설치했습니다.
이렇게해서 총 8대의 카메라에서 들어오는 영상을 동시에, 그리고 실시간으로 계속 분석하는데요. 이를 위해, 서버 위주로 시스템을 만들 수도 있겠죠. 즉 서버에 영상을 보내고, 서버에서 처리하는 식으로 구현할 수도 있겠습니다. 하지만 처리하게 될 동영상은 아주 고용량의 데이터이기 때문에, 이 데이터를 보내는것만 하더라도, 운영 비용에 많은 투자가 필요하게 됩니다. 이런 비용을 줄이고자 저희는 서버 대신에, 엣지 디바이스 단에서 추적을 수행하도록 설계하였습니다. 여기서 엣지 디바이스란, 입력 데이터를 가까이서 처리할 수 있는 소형 컴퓨터라고 이해하시면 되겠습니다.
엣지 디바이스 중에서도, 딥러닝 모델로 빠르게 추론 결과를 얻을 수 있는 것이 중요한데요. 그렇게 하기 위해서 GPU가 있는 기종이 필요합니다. 특히 Nvidia에서 출시한 Jetson 제품군을 이용한다면, 영상을 다루는 DeepStream과, GPU 추론 API인 tensorRT를 사용할 수 있는 장점이 있죠. 그 중에서도 저희는 연산량이 많으면서도, 비교적 저렴한 Jetson Xavier를 고르게 되었습니다.
유사 서비스를 제공하는 아마존 고를 보면요, 고가의 depth camera를 설치하고 그 카메라마다 하나의 엣지 디바이스를 연결하는 식으로 되어 있습니다. 이렇게 하면 시스템 구축 비용이 많이 들게 되는데요, 이 점이 아마존 고의 대중화를 어렵게 만드는 요인으로 잘 알려져 있습니다. 그래서 저희는 여러 대의 카메라를, 단 한 대의 엣지 디바이스에 연결하는 방식을 고려하게 되었고요, 그래서 합리적인 가격에 아마존 고와 유사한 성능을 내는, 시스템을 구축하는 데 집중했습니다.
Object Tracking Overview
저희가 만든 시스템의 흐름을 간략하게 표현해 보았는데요. 먼저 추적 대상을 찾는 Person detector가 있고요, 또 대상의 관절 위치를 찾는 Pose estimator, 이어서 매장 내 위치를 추정하는 multi-view geometry 모듈, 그리고 최종적으로 tracker를 거쳐서 사람을 추적하게 됩니다. 자세한 구현 방식은 각 장에서 좀 더 자세히 설명하겠습니다.
Person Detection
무인 편의점에서, 문을 열고 어떤 사람이 들어온다면, 카메라로 그걸 보고 사람이 있다는 걸 알아차려야 되겠죠? person detection은 바로, 영상에서 사람을 찾아내는 기술입니다.
detector에서 중요한 것은, 여러 사람이 밀집되어 있는 경우라던지 가려져서 잘 안보이는 경우에도 잘 작동해야 한다는 것입니다. 특히 저희 실험 환경에서는, 천장에 가까운-높은 위치에 카메라를 설치하기 때문에 그런 문제가 더 심각하게 되죠. 따라서 이 실제 환경과 되도록 유사한 데이터셋으로 학습하는 것이 중요하고요, 실제로 이에 맞는 데이터를 수집하여 학습에 활용했습니다.
detector는 tracking이 시작되는 지점이라고 할 수 있습니다. 사람을 검출한 이후에야 다른 모듈도 수행할 수 있겠죠. 이는 detector가 성능이 아주 중요하다는 걸 의미하기도 합니다.
검출기는 연산에 필요한 단계에 따라서 크게 두 가지로 나뉩니다. 먼저 one stage detector가 있는데요, 단 한 번만에 객체의 위치를 찾아내는 방법이고요, 반면, two stage detector는 두 단계로 이루어져 있습니다. 먼저 객체의 대략적인 위치를 찾는 단계가 있고요, 그후에 이를 보정하는 과정이 추가됩니다.
보통 two stage detector가 속도는 느리지만 더 정확하기 때문에, 이 방식의 검출기를 많이 사용하게 되죠. 하지만 저희는 내부적인 실험과 성능 개선 작업을 통해 one-stage detector로 만으로도 충분히 정확한 검출을 할 수 있다는 점을 확인했습니다.
추론 속도를 더 빠르게하기 위해서 pruning과 quantization와 같은 추가 기법을 사용할 수 있습니다. 이를 이용해서 정확도는 거의 유지하면서도 속도는 아주 빠르게할 수 있습니다. 하지만 이것만으로는 속도가 충분하지 않을 수 있죠. 이때 사용할 수 있는 방법 중 하나를 소개해 드리자면, 여기 그래프를 보면, 여러 개로 나뉘어져 있지만 하나로 간략화 할 수 있는 연산이 있죠. 또 추론에 불필요한 연산이 남아있는 경우도 있습니다. 그런 것을 고치는 작업을 할 수 있는데, 이를 그래프 최적화라고 합니다. 저희는 이것을 이용해서 약 20% 정도 속도를 높일 수 있었습니다.
이렇게하면, 여러 사람이 한꺼번에 들어오는 경우에도, 빠른 속도로 정확하게 검출하는 것을 확인할 수 있죠.
Pose Estimation
그리고 이어서, 사람의 신체 관절 위치를 찾는데요. 이때 사용되는 기술이 pose estimation이 되겠습니다.
pose를 찾는 것 역시 때때로 어려울 수 있는데요. detector와 마찬가지로 다른 사람이나 매대로 가려질 수 있고, 카메라 왜곡 또한 발생합니다. 따라서 이 부분에서도 실제 환경과 유사한 데이터를 수집하여 학습을 진행하게 되었습니다.
pose estimator 또한 두 가지로 분류할 수 있습니다. 우선, top-down 방식은, 영상에서 사람의 위치를 박스 형태로 찾은 다음에, 그 박스 내에서 pose를 찾는 방식이고요. 반면, bottom-up 방식은 이런 힌트 없이도 한 번에 pose을 찾는 방식입니다. detection 모듈이 따로 있기 때문에 저희는 top-down 방식의 pose estimator로 진행하였습니다.
그런데 문제는, 이 top-down 방식, 그러니까 검출한 박스 안에서 pose을 찾는 방식은요, 성능은 더 좋지만, 박스마다 각각 pose를 찾아야하는 단점이 있습니다. 때문에 사람이 많아지게 되면 처리 속도가 느려지게 되겠죠. 따라서 사람이 많은 경우에도 빠른 속도를 유지할 수 있도록 모델을 최대한 가볍게 만드는 게 정말 중요하게 되었습니다. 그래서 저희는 distillation 기법을 적극 이용해서 모델 크기를 대폭 줄이게 하였습니다. 이렇게 했을 때 성능은 약, 2% 정도 떨어지긴 하지만, 추론 속도는, 30% 이상, 향상시킬 수 있었습니다.
그렇게해서, 보시는 것과 같이, 14개의 관절 위치를 빠르게 찾는 것을 확인할 수 있습니다.
Multiple view Geometry
MultiView Geometry 는 3차원 공간 상에서 사람의 매장 내 현재 위치를 실시간으로 추정하는 단계입니다. 이 때, Person Detector 에서 얻은 box 정보와, Pose Estimator 에서 얻은 2차원 pose 정보를 이용합니다. 즉, 카메라의 정보를 활용해서 2차원 좌표 정보를 3차원 좌표 정보로 변환하는 단계라고 보시면 됩니다.
이미지는 3차원 공간에 있는 object 가, 카메라 렌즈와 센서를 통해 2차원으로 투영되면서, 깊이에 대한 차원 정보를 소실한 결과입니다. 이 말은 곧, 투영이라는 과정을 수식적으로 모델링할 수 있고, 2개 이상의 이미지를 통해 깊이를 추정한다면, 실제 3차원 공간 상의 위치 정보를 복원할 수 있다는 의미이기도 합니다.
투영 모델을 구성하는 값 중에서 중요한 요소는, 카메라 파라미터 K와 렌즈왜곡계수인 D입니다. 이 값은 렌즈의 종류, 이미지 센서와의 거리 및 각도 등, 카메라 내부의 기구적 요소에 따라 달라집니다. 그리고 동일한 모델명의 카메라라도, 미세한 제조 공정의 차이로 인해 그 값은 또 달라질 수 있죠. 따라서 모든 카메라마다 K와 D의 값을 정밀하게 측정하고, 이 값을 통해서 보정하는 camera calibration을 수행해야지만, 실제와 가까운 3차원 공간 정보를 획득할 수 있게 됩니다.
투영 모델 개발을 위해, 앞서 설명드린 K와 D 같은 카메라 하드웨어 정보 외에도, 카메라의 위치, 회전각, 카메라 간 상대적인 거리 등이 추가적으로 필요합니다. 최종 결과물의 허용 오차를 수 cm로 낮추기 위해서는, 이런 물리적 정보를 정확하게 측정하는 것 또한, 매우 중요합니다.
그 결과, 왼쪽 하단의 영상에서는 2D 공간에서 사람 위치를, 오른쪽 하단의 영상에서는 3D 공간에서 사람 위치를 확인할 수 있습니다. 사람의 움직임을 더 직관적으로 보여드리고자, 왼쪽 상단의 2D heatmap 과 오른쪽 상단의 이동경로도 함께 표현했습니다.
한편, 다른 모듈과는 달리, MultiView Geometry 는 딥러닝으로 구현하지는 않았습니다. 비전 기술만으로도 충분히 정확한 투영 모델을 만들 수 있었고, 서버에 비해 하드웨어 자원이 부족한 엣지 디바이스에서는, 계산량이 적은 구조의 모델 구현이 더 중요하기 때문입니다.
Object Tracking
그리고 마지막 단계인 Object Tracker 를 통해 사람을 추적하게 되는데요. 다중 카메라에서 찍은 영상을 실시간으로 분석하면서 추적 기능을 수행하면, 어떤 사람이 언제 들어왔는지, 어디 있었는지, 언제 나갔는지 등을 파악할 수 있게 됩니다.
Object Tracker 도 딥러닝에 기반한 추론 방식을 이용하는데요. 저희 세팅과 비슷한 종류의 트래킹 데이터를 구하는 것은 쉽지가 않았습니다. 따라서, 저희 비전룸에서 촬영된 영상을 학습 자료로 사용하였습니다. 물론, 사전에 크루원들에게 데이터 수집에 대해서는 사전 동의를 얻었습니다.
이 화면에서 볼 수 있듯이, 여러 카메라에 포착된 사람들을 추적해서, 이 사람이 어디에 있는지, 그 동선을 파악할 수 있게 됩니다. 그 결과, 같은 사람은 같은 색의 박스로 표시되는 것을 확인하실 수 있습니다.
System Integration
이 프로젝트의 전체적인 구조는, Nvidia 에서 제공하는 DeepStream 을 이용해 구성했습니다. DeepStream 은 멀티미디어 프레임워크인 Gstreamer를 기반으로 구성되어 있으며, Jetson 에 특화된 다양한 영상처리 기능을 포함하고 있습니다.
저희는 디코딩, 전처리 등의 기능은 DeepStream 이 제공하는 플러그인을, 별도로 필요한 모듈은 Gstreamer 플러그인을 직접 구현해서 사용했습니다. 추론 과정에서는 TensorRT를 이용했는데요. Pytorch 로 구현한 각 모델을 Onnx로, 그리고 이를 다시 TensorRT 로 변환하여 사용했습니다. 여기서는 각 모듈을 통합하고 진행하는 과정을, 순서에 따라 간단한 샘플 코드와 함께 소개해보고자 합니다.
첫 단계인 영상 디코딩은 DeepStream plugin 을 사용하여 진행했는데요. 이 때 동일한 시점에 촬영된 이미지가 있어야, 사람의 위치를 보다 정확하게 추정할 수 있습니다. 문제는, 카메라들의 스트리밍 속도가 제각기 다를 가능성이 크다는 거죠. 이를 해결하기 위해, 여러 카메라 간의 싱크를 맞추는 작업이 필요로 합니다. 먼저 각 카메라의 NTP 서버를 동일하게 설정해주어, 각 카메라의 시간정보를 동기화합니다. 그리고 예제 코드와 같이 “nvstreammux” 라는 플러그인을 생성할 때, “live-source”라는 옵션을 설정하면, 카메라 간의 싱크를 맞출 수 있게 됩니다.
그 다음, DeepStream 플러그인을 이용해 디코딩된 영상 데이터를, TensorRT에서 사용할 수 있는 형태로 포맷을 변환하는 과정을 거칩니다. 추가적으로, 영상 크기를 변환하는 과정에서는, DeepStream API 또는 CUDA 코드를 이용했는데요. 화면에서는 DeepStream API를 이용해, crop and resize 를 하는 예시를 보실 수 있습니다.
그 다음으로 추론 과정을 거치게 되는데, 이 때 미리 변환해둔 TensorRT 모델을 사용하게 됩니다. 각 모듈별로 직접 구현한 Gstreamer 플러그인 내에서, TensorRT API 를 호출하는 방식으로 구성했습니다. 이 과정에서, 앞서 설명드렸던 각 모듈들이 실행 됩니다. 각각의 모듈의 출력은 바로 다음 모듈의 입력이 되기에, 모듈별 추론이 순차적으로 진행될 수 있도록 구성했습니다. 예제 코드에서는 TensorRT API 를 이용해, 추론하는 간단한 과정을 확인할 수 있습니다.
추론을 통해 나온 결과 중에서, 필요한 경우 원하는 결과를 도출할 수 있도록 후처리 과정을 거치게 되는데요. 이 때는 TensorRT에서 제공하는 플러그인을 사용하거나, CUDA 코드로 별도로 구현하게 됩니다. 예제 코드에서는 TensorRT 플러그인 중에서 “Batched NMS” 플러그인을 추가하는 과정을 확인할 수 있습니다.
각각의 모듈로부터 나온 결과를 DeepStream API 를 이용해 metadata 에 저장합니다. 그런 뒤, DeepStream 플러그인을 이용해 metadata 를 시각처리해서 화면에 출력할 수 있습니다. 예시코드는 DeepStream API 를 이용해 Person Detection 의 결과를 metadata 에 저장하는 과정을 보여줍니다.
Object Tracking Overview
앞에서 설명 드린 각각의 모듈들을 모두 하나로 합치면 다음과 같은 형태가 됩니다. 다음 데모 영상을 보면서, 자세한 설명을 드리겠습니다.
가장 먼저, Person Detection 으로 사람을 박스 형태로 찾습니다. 그 다음, Pose Estimation 을 통해 pose 를 추정할 수 있게 되죠. 그 다음 단계에서는 각 카메라마다 여러 사람이 추적되는 모습을 확인해볼 수 있습니다. 그리고 우측 화면에서 Multiview Geometry 를 통해 사람의 매장 내 실시간 위치를 확인할 수 있습니다. 최종적으로, 다중 카메라 간의 사람이 추적되는 것을 볼 수 있습니다.
이렇게 만들어진 카카오엔터프라이즈 내 무인편의점 시스템은, 최대 7명의 움직임을 동시에 추적할 수 있습니다. 앞에서는 자세히 말씀을 드리지 못했지만, 현재 버전에서는 최대 수 kg 까지 측정이 가능하면서, 수 g 단위도 구별이 가능한 무게 센서로, 각 상품의 픽업 여부를 확인할 수 있습니다. 그 뿐만 아니라, 추적된 각 사람의 위치 정보에 기반해, 누가 물건을 들었는지도 포착하고 있죠.
향후 계획
물론 더 개선해야 할 점도 있습니다. 앞에서도 설명드렸지만, 카메라 배치와 매대로 인해 가림 현상이 심한데요. 이를 대처하기 위한 노력에도 불구하고, 여전히 여러 사람이 밀착하거나 엉켜있는 경우, 그 사람들의 위치 정보를 정확하게 분류하는데 한계가 있습니다. 이 여파로 물건을 잡은 사람이 누군지 정확하게 판단하는 데 있어서도 여전히 오류가 있죠.
이러한 문제를 해결하기위해, 카메라를 추가로 설치하여, 하나의 카메라에서 겹쳐보이는 경우에는, 또 다른 카메라를 통해 구별할 수 있게 만들어보고자 합니다. 특히, 사물이 얼마나 멀리에 위치했는지 알 수 있는 depth camera 의 도입을 검토 중이기도 합니다.
그리고, 각 모듈의 지속적인 경량화 및 최적화를 진행할 예정인데요. 그렇게 되면, 하나의 엣지 디바이스에서 처리할 수 있는 카메라가 늘어나고, 동시에 추적 가능한 사람의 수가 늘어날 것 입니다. 결과적으로, 전체 시스템에 필요한 엣지 디바이스의 수가 적어지기 때문에, 시스템 구축 비용이 감소하게 될 것입니다. 이것은 사업성과도 밀접한 연관이 있어서, 지속적으로 경량화 및 최적화를 진행하고자 합니다.
한편, 우리는 Pose Estimation 에서 검출된 결과를 통해, 사람의 자세를 판단할 수 있습니다. 그 중에서, 물건을 잡는 자세를 선별할 수 있다면, 누가 물건을 잡았는지를 정확히 알 수 있겠죠. 하지만 사람이 물건을 잡는 자세는 매우 다양하기 때문에, 이 검출된 결과와 더불어 손 부분의 영상을 사용하여, 사물 픽업 여부 판단을 고려하고 있습니다. 현재 PoC 단계에서는 적용되지 않은 기술로, 추후 검토를 진행할 계획입니다.