Depth(OAK-D)가 포함된 OpenCV AI Kit 프로그래밍에 대한 첫 번째 게시물입니다. 그리고 OpenCV AI Kit: Depth Lite(OAK-D-Lite)도 고려 되어있습니다. OAK-D-Lite는 OAK-D의 동생 정도로 생각하시면 됩니다.
OAK-D와 OAK-D Lite는 모두 Spatial AI 카메라입니다.
Spatial AI란?
Spatial AI는 비전(시각) AI 시스템이 아래 두 가지를 기반으로 결정을 내리는 능력입니다.
시각적 인식: AI가 주변을 시각적으로 “보고” “해석”하는 능력입니다. 예를 들어, 물체 감지를 위해 neural network을 실행하는 프로세서에 연결된 카메라가 카메라가 보고 있는 장면에서 고양이, 사람 또는 자동차를 감지할 수 있는 시스템입니다.
Depth 인식 : 이것은 물체가 얼마나 멀리 있는 지를 이해하는 AI의 능력입니다. 컴퓨터 비전 전문 용어에서 “깊이”는 단순히 “얼마나 멀리”를 의미합니다.
Spatial AI의 아이디어는 인간의 시각에서 영감을 받았습니다. 사람은 눈을 사용하여 주변 환경을 해석합니다. 또한 두 눈(즉, 스테레오 비전)을 사용하여 사물이 우리에게서 얼마나 멀리 있는지 인식합니다.
SPATIAL AI 카메라 OAK-D와 OAK-D-Lite
OAK-D와 OAK-D-Lite는 다음과 같은 중요한 구성 요소로 구성됩니다.
4K RGB 카메라 : 중앙에 위치한 RGB 카메라는 초고해상도 4k 영상을 촬영할 수 있습니다. 일반적으로 이 카메라는 시각적 인식에 사용됩니다.
스테레오 페어: 깊이(Depth) 인식에 사용되는 두 대의 카메라(“스테레오”라는 단어는 두 개를 의미함)의 시스템입니다.
Intel® Myriad™ X VPU(Visual Processing Unit): 이것은 OAK의 “두뇌”입니다. 시각적 인식을 위해 최신 Neural Networks을 실행하는 동시에 실시간으로 스테레오 페어의 이미지에서 깊이(Depth) 맵을 생성할 수 있는 강력한 프로세서입니다.
교육, 어린이 돌봄, 장애인 보조 기술, AR/VR, 드론을 사용한 창고 검사, 로봇 공학, 농업, 스포츠 분석, 소매 및 광고 분야의 응용 프로그램을 볼 수 있습니다.
OAK-D 및 OAK-D-Lite를 사용하여 구축된 더 많은 놀라운 애플리케이션을 보려면 리얼리에듀테크 블로그 페이지를 확인하세요..
이제 이 멋진 장치에 프로그래밍을 해보도록 하겠습니다. 고~~ 고~~
목차
OAK-D Vs OAK-D Lite
Depth AI 설치
왼쪽 모노 카메라에 액세스하는 Depth AI 파이프라인
스테레오 비전을 위한 완벽한 파이프라인
코드 다운로드
데모
OAK-D Vs OAK-D Lite
기능면에서 두 장치는 거의 동일합니다. OAK-D-Lite를 사용해도 OAK-D가 할 수 있는 거의 모든 작업을 수행할 수 있습니다. 그래서 초보자는 큰 차이를 느끼지 못할 것입니다. 그러나 아래 테이블과 같이 두 장치를 구분하는 몇 가지 사양이 있습니다. OAK-D Lite는 날렵하고 가볍고 저렴하며 전력을 덜 사용합니다. 반면에 OAK-D는 약간 더 높은 성능을 원하시는 고객이 선호 합니다.
OAK-D Vs OAK-D Lite 비교
특징/스펙
OAK-D
OAK-D-Lite
RGB 카메라
12 Megapixel, 4k, up to 60 fps
12 Megapixel, 4k, up to 60 fps
모노 카메라
1280x800p, 120 fps, 글로벌 셔터
640x480p, 120 fps, 글로벌 셔터
IMU(Inertial Measurement Unit)
Yes
No
USB-C, 파워 잭
Yes, Yes
Yes, No
VPU
Myriad-X, 4 trillion ops/s
Myriad-X, 4 trillion ops/s
설치
OAK-D 또는 OAK-D Lite를 사용하는 가장 좋은 점은 외부 하드웨어 또는 소프트웨어 종속성이 없다는 것입니다. 하드웨어, 펌웨어 및 소프트웨어가 통합되어 있어 쉬우면서도 빠르게 경험 할 수 있게 모든 것을 제공합니다. Depth-AI는 OAK-D를 프로그래밍하는 API(응용 프로그래밍 인터페이스)입니다. 크로스 플랫폼이므로 어떤 OS를 사용하는지 걱정할 필요가 없습니다. 이제 터미널이나 Powershell을 실행하여 API를 설치해 보겠습니다. 인터넷 연결 상태가 좋은 경우 약 30초가 소요됩니다.
파이프라인은 노드의 모음이고 노드는 입력과 출력이 있는 단위입니다. Depth-AI 파이프라인을 이해하기 위해 다음 그림을 살펴보겠습니다. 그림에서 주어진 명령이 실행될 때 카메라 내부에서 일어나는 일을 보여주고 있습니다. 왼쪽 모노 카메라에서 프레임을 캡처하는 매우 간단한 파이프라인입니다.
1. 파이프라인 생성
여기에서 파이프라인 객체를 인스턴스화합니다.
import depthai as dai pipeline = dai.Pipeline()
2. 카메라 노드 생성
아래 명령에 따라 모노 카메라 노드를 만듭니다. 시각적으로 아무것도 하지 않습니다. 모노 카메라만 인식합니다.
mono = pipeline.createMonoCamera()
3. 카메라 선택
카메라에 액세스하려면 이 경우 왼쪽 카메라를 선택해야 합니다. 이것은 setBoardSocket 메소드에 의해 수행됩니다. 내부적으로는 입력 노드인 X-LinkIn도 생성합니다. X-Link는 카메라가 호스트(컴퓨터)와 통신하는 데 사용하는 메커니즘입니다.
mono.setBoardSocket(dai.CameraBoardSocket.LEFT)
4. XLinkOut 노드 생성 및 프레임 획득
출력을 얻으려면 X-Link 출력 노드를 만들어야 합니다. 카메라는 몇 가지 다른 출력을 가질 수 있습니다. 예를 들어 오른쪽 모노 카메라나 RGB 카메라의 다른 스트림 또는 현재로서는 걱정할 필요가 없는 다른 출력이 있습니다. 따라서 다른 사람과 충돌하지 않도록 “Left”으로 명명되었습니다. 마지막으로 X-LinkOut 노드에 입력으로 넣어 모노 카메라의 출력을 연결합니다.
이전 코드까지는 장치 준비 까지 완료한 상태입니다. 따라서 실제로는 아무 것도 처리하지는 않았습니다. 모든 명령은 호스트 컴퓨터 내부에서 실행되었습니다. 따라서 전처리 단계라고 생각하시면 됩니다. 다음 코드 사용하여 파이프라인을 호스트 컴퓨터에서 카메라로 전송합니다.
이제 X-LinkOut 노드에서 출력 프레임을 얻을 수 있습니다. X-LinkOut 노드의 출력은 단일 프레임이 아닙니다. 실제로 여러 프레임을 저장할 수 있는 큐(Queue)를 만듭니다. 여러 프레임이 필요한 특정 응용 프로그램에 유용할 수 있습니다. 비디오 인코딩이 그러한 예입니다. 그러나 우리의 경우 여러 프레임이 필요하지 않습니다. 따라서 지금은 기본 단일 프레임으로 유지하겠습니다. 아래 코드를 보시다시피 큐(Queue)은 스트림을 지정하는 getOutputQueue 메서드를 사용하여 가져옵니다.
다음으로 프레임을 추출하기 위해 큐(Queue)에 쿼리합니다. 이 시점에서 프레임은 장치에서 호스트 컴퓨터로 전송됩니다. 프레임은 여러 유형을 가질 수 있는 depthai.ImgFrame 클래스입니다. OpenCV에서 쉽게 사용하게 만들기 위해 이미지를 numpy 배열로 반환하는 getCvFrame 함수를 사용합니다. 이것으로 기본 파이프라인을 마칩니다.
with dai.Device(pipeline) as device:
queue = device.getOutputQueue(name="left")
frame = queue.get()
imOut = frame.getCvFrame()
이제 왼쪽 및 오른쪽 카메라 모두를 위한 완전한 파이프라인을 구축해 보겠습니다. 모노 카메라의 출력을 사용하여 별도 보기와 병합 보기를 표시합니다. 본격 적으로 시작하기 위해 다음 링크를 사용하여 전체 코드를 다운로드하세요.
def getFrame(queue): # Get frame from queue frame = queue.get()
# Convert frame to OpenCV format and return return frame.getCvFrame()
모노 카메라 선택 기능
여기에서 파이프라인에 대한 카메라 노드가 생성됩니다. 그런 다음 setResolution 메서드를 사용하여 카메라 해상도를 설정합니다. sensorResolution 클래스에는 선택할 수 있는 다음 속성이 있습니다.
THE_700_P (1280x720p)
THE_800_P (1280x800p)
THE_400_P (640x400p)
THE_480_P (640x480p)
우리의 경우 해상도를 640x400p로 설정합니다. 보드 소켓은 isLeft 부울을 사용하여 왼쪽 또는 오른쪽 모노 카메라로 설정됩니다.
def getMonoCamera(pipeline, isLeft):
# Configure mono camera
mono = pipeline.createMonoCamera()
# Set Camera Resolution
mono.setResolution(dai.MonoCameraProperties.SensorResolution.THE_400_P)
if isLeft:
# Get left camera
mono.setBoardSocket(dai.CameraBoardSocket.LEFT)
else :
# Get right camera
mono.setBoardSocket(dai.CameraBoardSocket.RIGHT)
return mono
메인 기능
파이프라인 및 카메라 설정
먼저 파이프라인을 만들고 왼쪽 및 오른쪽 모노 카메라를 설정합니다. 미리 정의된 함수 getMonoCamera는 내부적으로 X-LinkIn 노드를 생성하고 모노 카메라 출력을 반환합니다. 그런 다음 카메라의 출력이 X-LinkOut 노드에 연결됩니다.
if __name__ == '__main__':
pipeline = dai.Pipeline()
# Set up left and right cameras
monoLeft = getMonoCamera(pipeline, isLeft = True)
monoRight = getMonoCamera(pipeline, isLeft = False)
# Set output Xlink for left camera
xoutLeft = pipeline.createXLinkOut()
xoutLeft.setStreamName("left")
# Set output Xlink for right camera
xoutRight = pipeline.createXLinkOut()
xoutRight.setStreamName("right")
# Attach cameras to output Xlink
monoLeft.out.link(xoutLeft.input)
monoRight.out.link(xoutRight.input)
파이프라인을 디바이스로 전송
설정이 준비되면 파이프라인을 디바이스(카메라)로 전송합니다. 왼쪽 및 오른쪽 카메라 출력에 대한 큐(Queue)은 각각의 이름으로 정의됩니다. 프레임 보유 용량은 maxSize 인수로 설정되며 이 경우에는 단일 프레임으로 설정합니다. 나중에 출력을 표시하는 데 사용할 명명된 윈도우(Stereo Pair)도 생성됩니다. sideBySide 변수는 카메라 보기(나란히 보기 또는 중첩 보기)를 전환하기 위한 부울 값입니다.
with dai.Device(pipeline) as device:
# Get output queues.
leftQueue = device.getOutputQueue(name="left", maxSize=1)
rightQueue = device.getOutputQueue(name="right", maxSize=1)
# Set display window name
cv2.namedWindow("Stereo Pair")
# Variable used to toggle between side by side view and one
frame view.
sideBySide = True
메인 loop
지금까지 파이프라인을 만들고 카메라 출력을 X-LinkOut 노드에 연결하고큐(Queue)을 얻었습니다. 이제 미리 정의된 getFrame 함수를 사용하여 프레임을 쿼리하고 OpenCV 친화적인 numpy 배열 형식으로 변환할 시간입니다. 나란히 보기의 경우 프레임이 numpy hstack(수평 스택) 기능을 사용하여 수평으로 연결됩니다. 중첩 출력의 경우 강도(intensity)를 2배로 줄여 프레임을 추가하기만 하면 됩니다.
키보드 입력 q는 루프를 종료하고, t는 디스플레이를 토글합니다(나란히 보기 및 정면 보기).
while True:
# Get left frame
leftFrame = getFrame(leftQueue)
# Get right frame
rightFrame = getFrame(rightQueue)
if sideBySide:
# Show side by side view
imOut = np.hstack((leftFrame, rightFrame))
else :
# Show overlapping frames
imOut = np.uint8(leftFrame/2 + rightFrame/2)
# Display output image
cv2.imshow("Stereo Pair", imOut)
# Check for keyboard input
key = cv2.waitKey(1)
if key == ord('q'):
# Quit when q is pressed
break
elif key == ord('t'):
# Toggle display when t is pressed
sideBySide = not sideBySide
결과
그림: 나란히 보기
그림: 중첩 출력
결론
이것으로 Depth가 포함된 OpenCV AI Kit 소개를 마칩니다. 가볍게 읽고 OAK-D 설정에 대한 아이디어를 얻으셨기를 바랍니다. 다음 블로그 게시물에서는 OAK-D에서 Depth 맵을 가져오는 파이프라인을 다룰 것입니다.