知之者 不如好之者, 好之者 不如樂之者

기계처럼 살지 말고, 즐기는 인간이 되자

Project/ROS2 + CV + Robot (2023.12~2024.02)

Intel RealSense 카메라 + YOLOv8 을 이용한 object 거리 추출

코방코 2024. 1. 12. 13:55
728x90

 


Python OpenCV를 이용해서 YOLOv8과 함께 묶어,

Intel RealSense L515와 D435를 통해 특정 오브젝트가 감지되었을 때,

해당 object의 깊이 정보를 받아오는 과정을 수행해보겠습니다.
 
YOLO가 필요없으신 분들은 아래 글을 참조하시기 바랍니다.

 

Intel Realsense를 이용한 Python openCV 영상 처리

최종적으로 시각 정보를 사용하기 위해 Intel RealSense Viewer 를 사용할 것이 아니고, python3 openCV를 이용해서 RGB Stream과 Depth Stream 을 가져오고 python에서 정보를 처리하길 원했기 때문에 이를 구현한

cobang.tistory.com

 
참조한 좋은 레퍼런스 입니다.

 

리얼센스 카메라를 활용한 yolov8 기반 human detection

리얼센스 카메라를 이용하여 yolov8을 활용하여 실시간 object detection을 진행하는 과정을 보여준다. 리얼센스 제품은 L515이다. 우선 리얼센스 L515 카메라 셋팅 먼저 진행하겠다. # Create a config and conf

hjdevelop.tistory.com

 


가상환경 구성과 OpenCV 4.9.0 빌드

저는 Linux ubuntu 22.04 환경에서 이 task를 수행했기 때문에,

먼저 Python3.9를 이용하는 yolo 가상환경을 만들겠습니다.

conda create -n yolo python=3.9

conda activate yolo

 
가장 먼저 yolov8 구동을 위한 pytorch와 ultralytics 부터 설치해주겠습니다.

conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia

pip install ultralytics

ultralytics를 설치하면 torch와 torchvision은 이미 깔려있어서 skip이 되고,

OpenCV는 새로 설치하게 됩니다.
 
저는 충돌을 방지하기 위해 OpenCV를 다시 삭제해주었습니다.

CUDA 기반의 OpenCV 처리가 필요없는 분들은 아래 명령어와,

cmake 과정을 수행할 필요가 없습니다.

pip uninstall opencv-python

 
OpenCV 빌드를 위해 아래 패키지 설치 과정을 수행합니다.

이미 예전에 수행하셨다면 가장 위 두 줄만 수행하시기 바랍니다.

conda install numpy

conda install -c conda-forge cmake

sudo sh -c "echo '/usr/local/cuda/lib64' >> /etc/ld.so.conf.d/nvidia-tegra.conf"

sudo ldconfig

sudo apt-get install build-essential cmake git unzip pkg-config

sudo apt-get install libjpeg-dev libpng-dev libtiff-dev

sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev

sudo apt-get install libgtk2.0-dev libcanberra-gtk*

sudo apt-get install python3-dev python3-numpy python3-pip

sudo apt-get install libxvidcore-dev libx264-dev libgtk-3-dev

sudo apt-get install libtbb2 libtbb-dev libdc1394-22-dev

sudo apt-get install libv4l-dev v4l-utils

sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

sudo apt-get install libvorbis-dev libxine2-dev

sudo apt-get install libfaac-dev libmp3lame-dev libtheora-dev

sudo apt-get install libopencore-amrnb-dev libopencore-amrwb-dev

sudo apt-get install libopenblas-dev libatlas-base-dev libblas-dev

sudo apt-get install liblapack-dev libeigen3-dev gfortran

sudo apt-get install libhdf5-dev protobuf-compiler

sudo apt-get install libprotobuf-dev libgoogle-glog-dev libgflags-dev

sudo nano ~/.bashrc

export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH

source ~/.bashrc

 
이제 OpenCV 4.9.0 버전을 설치해주겠습니다.

저는 홈 디렉토리에 예전에 빌드했던 opencv, opencv_contlib 디렉토리가 있어서

rm -rf 명령으로 삭제하고 clone 해주었습니다.

cd

OPENCV_VERSION=4.9.0

git clone https://github.com/opencv/opencv.git -b ${OPENCV_VERSION}

git clone https://github.com/opencv/opencv_contrib.git -b ${OPENCV_VERSION}

cd opencv

 
이제 cmake를 해줍니다.

cmake \
-G "${GENERATOR_NAME}" \
-B build \
-D CMAKE_INSTALL_PREFIX=~/anaconda3/envs/yolo \
-D BUILD_CUDA_STUBS=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_JASPER=OFF \
-D BUILD_JPEG=OFF \
-D BUILD_OPENEXR=OFF \
-D BUILD_PACKAGE=ON \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_PNG=OFF \
-D BUILD_SHARED_LIBS=ON \
-D BUILD_TBB=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_TIFF=OFF \
-D BUILD_WITH_DEBUG_INFO=ON \
-D BUILD_ZLIB=OFF \
-D BUILD_WEBP=OFF \
-D BUILD_opencv_apps=ON \
-D BUILD_opencv_calib3d=ON \
-D BUILD_opencv_core=ON \
-D BUILD_opencv_cudaarithm=ON \
-D BUILD_opencv_cudabgsegm=ON \
-D BUILD_opencv_cudacodec=OFF \
-D BUILD_opencv_cudafeatures2d=ON \
-D BUILD_opencv_cudafilters=ON \
-D BUILD_opencv_cudaimgproc=ON \
-D BUILD_opencv_cudalegacy=ON \
-D BUILD_opencv_cudaobjdetect=ON \
-D BUILD_opencv_cudaoptflow=ON \
-D BUILD_opencv_cudastereo=ON \
-D BUILD_opencv_cudawarping=ON \
-D BUILD_opencv_cudev=ON \
-D BUILD_opencv_dnn=ON \
-D BUILD_opencv_features2d=ON \
-D BUILD_opencv_flann=ON \
-D BUILD_opencv_gapi=ON \
-D BUILD_opencv_highgui=ON \
-D BUILD_opencv_imgcodecs=ON \
-D BUILD_opencv_imgproc=ON \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_js=OFF \
-D BUILD_opencv_ml=ON \
-D BUILD_opencv_objdetect=ON \
-D BUILD_opencv_photo=ON \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=ON \
-D BUILD_opencv_stitching=ON \
-D BUILD_opencv_ts=ON \
-D BUILD_opencv_video=ON \
-D BUILD_opencv_videoio=ON \
-D BUILD_opencv_world=OFF \
-D CMAKE_BUILD_TYPE=Release \
-D CUDA_ARCH_BIN=${CUDA_ARCH_BIN} \
-D CUDA_ARCH_PTX="" \
-D OPENCV_DNN_CUDA=ON \
-D PYTHON_EXECUTABLE=~/anaconda3/envs/yolo/bin/python3.9 \
-D PYTHON_INCLUDE_DIR=~/anaconda3/envs/yolo/include/python3.9 \
-D PYTHON_LIBRARY=~/anaconda3/envs/yolo/lib/libpython3.9.so \
-D OPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules \
-D OPENCV_PYTHON_INSTALL_PATH=~/anaconda3/envs/yolo/lib/python3.9/site-packages \
-D WITH_1394=OFF \
-D WITH_CUBLAS=ON \
-D WITH_CUDA=ON \
-D WITH_CUFFT=ON \
-D WITH_CUDNN=ON \
-D WITH_EIGEN=ON \
-D WITH_FFMPEG=ON \
-D WITH_GDAL=OFF \
-D WITH_GPHOTO2=OFF \
-D WITH_GIGEAPI=OFF \
-D WITH_GSTREAMER=OFF \
-D WITH_GTK=OFF \
-D WITH_INTELPERC=OFF \
-D WITH_IPP=ON \
-D WITH_IPP_A=OFF \
-D WITH_JASPER=ON \
-D WITH_JPEG=ON \
-D WITH_LAPACK=ON \
-D WITH_LIBV4L=ON \
-D WITH_OPENCL=OFF \
-D WITH_OPENCLAMDBLAS=OFF \
-D WITH_OPENCLAMDFFT=OFF \
-D WITH_OPENCL_SVM=OFF \
-D WITH_OPENEXR=ON \
-D WITH_OPENGL=ON \
-D WITH_OPENJPEG=ON \
-D WITH_OPENMP=OFF \
-D WITH_OPENNI=OFF \
-D WITH_PNG=ON \
-D WITH_PTHREADS_PF=ON \
-D WITH_PVAPI=OFF \
-D WITH_QT=ON \
-D WITH_TBB=OFF \
-D WITH_TIFF=OFF \
-D WITH_UNICAP=OFF \
-D WITH_V4L=ON \
-D WITH_VTK=ON \
-D WITH_WEBP=ON \
-D WITH_XIMEA=OFF \
-D WITH_XINE=OFF \
.

 
이제 빌드를 해줍니다.

cd build

make -j$(nproc)

sudo make install

 
정상적으로 빌드가 되었는지 확인합니다.

python3 -c 'import cv2; print(cv2.getBuildInformation())'

 
마지막으로 pyrealsense2를 설치해줍니다.

pip install pyrealsense2

 


Yolov8 + RealSense 코드 구현 및 실행

 
이제 준비가 완료되었으니 yolov8을 이용해서 L515 (D435)를 작동시켜보겠습니다.

일단 디렉토리를 하나 만듭니다.

mkdir yolov8_depth

cd yolov8_depth

 
다음과 같은 코드를 해당 디렉토리에 넣어줍니다.

간단하게 pipeline으로 받은 stream을 yolov8 으로 분석하고,

그 중 사람을 targeting하여 박스를 그리고, 박스의 중심에 대해 거리를 측정합니다.
 

 
 
실행시킵니다.
 
만약 다음과 같은 ImportError 가 나타나면

/lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found

gcc 호환 에러라고 하니 gcc를 업그레이드 하여 해결 해줍니다.

conda install -c conda-forge gcc=12.1.0

 
 
L515로 실행한 결과 입니다.

 
일단 person label에 대해 conf와 거리가 함께 출력되도록 하였고,

필요 시 적절하게 class, 그 외에 점의 위치 등을 옮겨

거리에 따라 특정 명령을 쏘는 것으로 발전 시킬 수 있을 것 입니다.
 

 
다만 L515의 경우 50cm 이내로 가까워졌을 때,

물체의 거리를 인식못하는 단점이 있습니다.

 
또한, 3m 정도가 되면 인식이 되지 않습니다.

 
D435로도 테스트해보았는데,

최소 20cm 정도를 탐지하고 (사실상 이보다 가까우면 물체 인식이 불가)

 
D435는 거리가 10m 정도 떨어져도 카메라에 물체가 인식된다면 거리가 표시됩니다.

 
 
이러한 차이는 두 카메라의 거리 측정 방식 차이에서 기인합니다.

Intel RealSense D435와 L515는 서로 다른 Depth 측정 기술을 사용하기 때문에

각각의 거리 인식 범위와 성능에 차이가 있습니다.
 

D435는 스테레오 비전(stereo vision)을 사용합니다.

이 기술은 두 개의 카메라를 사용하여 객체의 깊이를 추정합니다.

이러한 방식은 인간의 두 눈처럼 작동하여,

두 이미지 간의 차이(변위)를 이용하여 깊이를 계산합니다.
 

스테레오 비전 카메라는 일반적으로 넓은 거리 범위를 커버할 수 있지만,

매우 가까운 거리에서는 효과적으로 깊이를 측정하기 어렵습니다.

이는 카메라 간의 물리적 거리(기준선)가 제한적이기 때문에,

매우 가까운 거리에서는 두 이미지 간의 차이가 충분히 크지 않을 수 있기 때문입니다.

따라서 D435는 일반적으로 중,장거리 깊이 측정에 적합합니다.
 

L515는 LiDAR(Light Detection and Ranging) 기술을 사용합니다.

LiDAR는 레이저 펄스를 발사하고 그 펄스가 객체에 반사되어 돌아오는 시간을 측정하여 거리를 계산합니다.
 
LiDAR 기반 시스템은 일반적으로 중거리 거리 측정에 최적화되어 있으며,

정확도와 해상도가 매우 높습니다.

그러나, LiDAR 시스템은 레이저 펄스의 최소 비행 시간으로 인해 매우 가까운 거리에서는 효과적으로 측정하기 어려울 수 있습니다.

반면, 매우 먼 거리에서는 레이저 신호가 약해져 정확도가 떨어질 수 있습니다.

따라서 L515는 주로 정밀한 중거리 깊이 측정에 적합합니다.
 

상황에 맞게 적절하게 선택해서 사용하면 될 것 같습니다.
 
 

 

728x90
반응형