딥러닝을 위한 cuda 지원 opencv 설치 및 활용 방법 (with Python + Windows 10)

2021. 9. 8. 17:57IT, 데이터/Python(파이썬)

728x90

 

 

opencv는 c++ 기반의 영상, 이미지 처리 오픈소스 라이브러리로 많이 활용되고 있는데요.

 

몇 년전부터 딥러닝 기술이 많이 이루어지면서 대용량 데이터 학습 및 처리를 위해 속도 향상을 위해 GPU의 중요성이 올라가고 있어서, opencv 4.2 버전부터는 라이브러리 자체에서 NVIDIA GPU 가속 기술인 cuda를 지원하고 있습니다.

 

하지만 막상 opencv에서 cuda 가속을 사용하려면 단순히 인터넷이나 서버에서 라이브러리를 다운받아 쓰는 게 아니라, 사용자의 하드웨어 및 개발환경에 맞춰서 라이브러리를 생성하는 빌드(build) 작업을 해주어야 하는데,

 

이 과정이 꽤 번거로울 뿐 아니라 시간도 엄청 오래 걸리고(2시간 이상) 사용자 컴퓨터에 따라 인터넷을 보고 따라해도 잘 안되는 경우가 많아서 여간 스트레스가 아닙니다.

 

저도 윈도우 컴 2개와 리눅스 컴 하나로 시도했는데도 다 중간에 에러가 뜨거나 파일이 생성되야 하는데 안나오거나 하는 등 문제가 있어서 장장 1주일 넘게 설치했다 지웠다를 반복하고 나서야 겨우 성공했네요.

 

그래서 이번에는 윈도우 환경에서 cmake를 통해 opencv를 빌드하는 방법 중에 제일 간편하고 시간이 적게 걸리는 방법을 설명드리고, python에서 opencv 코드로 cuda 가속을 적용하는 것 까지 해보도록 하겠습니다.

 

 

이번 글 작성을 위해 참고하였고 opencv 빌드 방법에 대해 잘 소개되어 있는 두 개 자료를 먼저 소개합니다.

 

            - https://jamesbowley.co.uk/build-opencv-with-cuda-in-windows/

 

Build OpenCV with CUDA in Windows - James Bowley

Links to guides for building various versions of OpenCV with CUDA OpenCV 4.5.0 with CUDA 11.1, Nvidia Video Codec SDK, Nvidia cuDNN, Intel Media SDK, Intel’s Math Kernel Libraries (MKL), Intel Threaded Building Blocks (TBB) performance libraries and pyth

jamesbowley.co.uk

    

윈도우에서 opencv cuda 빌드 관련 가장 종합적인 내용을 알려주는 사이트입니다.

여기서는 터미널과 ninja를 활용해 좀 더 쉽고 빠르게 opencv 빌드할 수 있는 방법을 소개하고 있어서 이번 글에서 가장 많이 참고하였습니다.

 

더불어 이 사이트에서는 opencv 빌드가 어려운 사람들을 위해 여러 파이썬 및 cuda 버전에 따라 opencv를 미리 빌드해놓은 파일들을 제공하고 있어서 본인 환경에 맞는 버전이 있다면 수동으로 빌드작업 할 필요없이 여기서 바로 다운받아서 사용해도 됩니다.

 

 

        - https://www.youtube.com/watch?v=Gfl6EyIhFvM&t=2739s

파일 다운로드부터 차근차근 보면서 opencv 빌드를 따라할 수 있는 우리나라 유튜브 강의입니다.

우리나라 말로 되어있는 것 중에는 제일 친절하게 설명되어 있는 것 같습니다.

 

 

1. 사전 설치 프로그램


C++ 뿐만 아니라 파이썬 버전으로 opencv cuda 지원 라이브러리 빌드를 위해 사전에 설치되어야 하는 프로그램입니다. 저는 파이썬으로 opencv를 활용하는 것을 보여드리지만, 만약 파이썬을 사용하지 않으시면 2번, python 또는 anaconda 설치가 필요없습니다. 

 

1)    Cuda toolkit cudnn : GPU 모델 및 드라이버 호환성 확인 후 적절한 버전을 설치합니다.

 

2)    Python (또는 anaconda) : python은 64비트 버전으로 설치하며, anaconda가 아닌 python 환경을 활용할 경우 numpy 패키지를 추가로 설치합니다.

 

3)    CMake : 소프트웨어 빌드 및 패키지 제작 도구로 사용자 환경에 맞는 opencv 패키지 빌드 세팅을 위해 활용. 아무 최신 버전(3.21)을 활용해도 무방할 것으로 보임. (테스트는 3.18버전으로 진행함). msi 확장자로 된 windowsbinary distribution 파일을 다운로드 후 설치합니다.
https://cmake.org/download/

 

4)    Microsoft visual studio : 2019 버전을 추천하며, 무료버전인 community 버전으로 설치하며, 구성요소 중 ‘C++를 사용한 데스크톱 개발을 선택한 후 설치합니다.
https://visualstudio.microsoft.com/ko/downloads/

 

5)    Opencv 소스 파일 : 아래 링크 두 개에 들어가서 각각 opencv 소스코드와 opencv_contrib 소스코드를 각각 같은 버전으로 다운받습니다. 첫번째 링크 들어가면 다운받을 수 있는 파일이 여러개 있는데 하단에 'source code'(zip) 이라고 되어있는 것을 받으면 되고, opencv_contrib의 경우 해당 버전의 zip 파일을 받으면 됩니다.

https://github.com/opencv/opencv/releases
https://github.com/opencv/opencv_contrib/releases

 

1)~4)까지 프로그램 설치를 완료하고, 5) 소스 파일을 내려받고나면,

예를 들어 위와 같이 빌드 작업을 위해 아무 경로에 'opencv' 등과 같이 폴더를 하나 생성하고, 그 안에 opencv, opencv_contrib 압축파일을 이동시킨 다음 각각 파일명 폴더에 압축을 풀면 일단 빌드 작업을 위한 준비가 모두 끝납니다.

 

 

 

2. 빌드 파일 생성


opencv 빌드파일 생성은 위에서 설치했던 cmake 프로그램을 이용합니다.

cmake를 이용하는 방법은 GUI 환경 또는 터미널에서 명령어를 입력하는 방법 둘 다 가능한데,

차근차근 따라하기에는 GUI 방식이 좋긴하지만, 빠르게 다른 사람이 해놓은 세팅을 복붙해서 쓰기에는 명령어 방식이 더 좋기 때문에 저는 복붙해서 쓸 수 있게 명령줄 방식을 활용하도록 하겠습니다.

 

(GUI 활용방법은 위의 동영상 강의에서 친절히 알려줍니다.)

 

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
set "openCvSource=C:/opencv/opencv-4.5.0"
set "openCVExtraModules=C:/opencv/opencv_contrib-4.5.0/modules"
set "openCvBuild=%openCvSource%/build"
set "buildType=Release"
set "generator=Ninja"
set "pathToPython=C:/Users/OOOO/AppData/Local/Programs/Python/Python37"
set "pyVer=37"
"C:\Program Files\CMake\bin\cmake.exe" -B"%openCvBuild%/" -H"%openCvSource%/" -G"%generator%" -DCMAKE_BUILD_TYPE=%buildType% -DOPENCV_EXTRA_MODULES_PATH="%openCVExtraModules%/" ^
-DINSTALL_TESTS=ON -DINSTALL_C_EXAMPLES=ON -DBUILD_EXAMPLES=ON ^
-DBUILD_opencv_world=ON ^
-DWITH_CUDA=ON -DCUDA_TOOLKIT_ROOT_DIR="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.1" -DCUDA_FAST_MATH=ON -DWITH_CUBLAS=ON -DCUDA_ARCH_BIN=8.6 -DWITH_NVCUVID=ON ^
-DWITH_OPENGL=ON ^
-DWITH_MFX=ON ^
-DBUILD_opencv_python3=ON -DPYTHON3_INCLUDE_DIR=%pathToPython%/include -DPYTHON3_LIBRARY=%pathToPython%/libs/python%pyVer%.lib -DPYTHON3_EXECUTABLE=%pathToPython%/python.exe -DPYTHON3_NUMPY_INCLUDE_DIRS=%pathToPython%/lib/site-packages/numpy/core/include -DPYTHON3_PACKAGES_PATH=%pathToPython%/Lib/site-packages/ -DOPENCV_SKIP_PYTHON_LOADER=ON

 

윈도우 명령 프롬프트(cmd)에 들어가셔서 위의 코드를 복사해서 실행하면 소스 파일이 생성되는데요.

여기서 몇 가지 경로나 옵션을 본인의 컴퓨터 환경에 맞게 고쳐서 쓰면 됩니다.

 

상단의 set 부분은 경로 등을 설정하는 부분이고, 하단의 '-D' 로 시작하는 옵션들은 opencv 빌드 시 포함할 옵션들입니다. 위의 명령줄에는 cuda 가속 지원을 위한 '-DWITH_CUDA=ON', opencv 파이썬 패키지 생성을 위한 'DBUILD_opencv_python3=ON' 등이 세팅되어 있습니다.

 

위의 코드에서 사용자에 따라 고칠 부분은 다음과 같습니다.

 

1) #1~#3, #7, #12 : 비주얼 스튜디오 설치경로, opencv 소스파일 경로, 파이썬 설치 경로, cuda 설치 경로로 본인의 설치 경로에 맞게 고쳐줍니다.

2) #8 : 파이썬 버전으로 7번째 줄에서 설정된 경로에 있는 파이썬 버전을 입력합니다. 예를들어 3.7버전인 경우 '37', 3.6버전인 경우 '36'과 같이 입력합니다.

3) #12 : 중간에 '-DCUDA_ARCH_BIN=8.6' 이라는 부분이 있는데, 여기에서는 본인 컴퓨터에 설치된 그래픽카드의 기종을 확인한 후 모델에 해당하는 그래픽카드 버전을 입력합니다.

 

그래픽카드 모델별 버전은 아래 위키피디아 사이트에서 확인할 수 있고, 위키 문서에서 아래로 내리다보면 'GPUs Supported' 항목에 아래와 같은 커다란 표가 있습니다. 여기서 컴퓨터에 설치된 Nvidia 그래픽카드 모델을 찾고 해당되는 줄의 맨 왼쪽 칸에 해당하는 숫자(6.1, 7.2, 8.6 등)를 '-DUCDA_ARCH_BIN=00' 에 넣어주면 됩니다. 

 

https://en.wikipedia.org/wiki/CUDA

 

 

경로와 버전 수정이 완료되면 해당 코드를 복사하여, 명령프롬프트에 붙여넣고 실행하면 아래와 같은 화면이 출력되는데, 맨 아래에 'Configuring Done', 'Generating Done', 'Build files have been written to : 경로' 와 같은 안내 메시지가 나오면 정상적으로 빌드 파일이 생성된 것입니다.

 

빌드 파일은 아래 경로와 같이 'C:/opencv/opencv-4.5.0/build' 에 생성된 것을 알 수 있습니다.

 

 

 

3. Visual Studio Ninja를 활용한 opencv 패키지 빌드


2번 과정에서 생성된 빌드 파일은 visual studio 솔루션 형태로 생성되어 있어서, 비주얼 스튜디오로 솔루션 파일을 열어서 '솔루션 빌드'를 실행하면 됩니다... 만 이번과 같이 cuda 가속 기능이 포함된 경우 빌드 시간이 짧게는 2시간에서 길게는 5시간까지로 매우 오래 걸립니다.

 

그래서 이번에는 비주얼 스튜디오에서 직접하는 대신, cmake가 지원하는 서드파티 빌드 시스템인 ninja를 활용해서 빌드해보겠습니다. ninja로 빌드할 경우 저의 경우 1시간 미만(30~40분 정도) 소요되었고, 현재 어느정도까지 진행 중인지 확인이 편리해서 괜찮은 방법이라고 생각합니다.

 

"C:\Program Files\CMake\bin\cmake.exe" --build %openCvBuild% --target install

 

ninja로 빌드하려면 명령 프롬프트에서 위의 명령줄을 치고 실행하면 바로 빌드가 진행됩니다.

 

빌드 진행 중에는 위와 같이 경고나 에러발생 내역이 뜨는데, 반복적으로 뜨는 warning은 무시하셔도 되나, 중간에 빨간색으로 'FAILED' 가 뜨면 즉시 작업이 중단되니 에러내용을 확인하고 경로가 잘못됐거나 파일이 빠져있는 지 등은 체크한 후 다시 빌드를 진행해야 합니다.

 

위의 에러 메시지의 경우 빌드 경로에 한글이 포함되어 있어서('opencv_임시') 발생한 것으로, 경로를 영문으로 수정하고 다시 실행하니 정상적으로 빌드가 되었습니다.

 

 

 

4. 빌드 후 후속 설정


 

opencv 빌드가 완료된 후 opencv 작동 여부를 아래 커맨드로 확인할 수 있습니다.

 

"%openCvBuild%\install\x64\vc16\bin\opencv_perf_cudaarithm.exe" --gtest_filter=Sz_Type_Flags_GEMM.GEMM/29

 

 

정상적으로 GPU 인식 및 cuda 가속이 작동될 경우 위와 같이 GPU 모델과 cuda 버전이 표시되고, 초록색 글씨로 RUN, OK 표시가 나옵니다.

 

 

그 다음에는 윈도우에 opencv 환경변수를 설정합니다.

 

명령 프롬프트에서 'systempropertiesadvanced' 입력 후 엔터키를 치거나, 제어판 - 시스템 설정 고급 탭으로 간 후,

우측 하단 환경 변수클릭 후 시스템 변수에서 새로 만들기’를 클릭합니다.

 

맨 아래 그림과 같이 변수 이름을 ‘OPENCV_DIR’로 지정하고, 변수값은 '(opencv 빌드 경로)\install' 로 지정 후 확인 버튼을 누릅니다.

그 다음에는 시스템 변수 중에 'path' 항목 선택 후 편집 버튼을 클릭하고, 아래의 우측과 같은 화면에서 '새로 만들기' 버튼 클릭 후 '%OPENCV_DIR%\x64\vc16\bin' 을 입력하고 확인 버튼을 눌러 닫습니다.

 

마지막으로 opencv 빌드 과정에서 생성된 python 패키지 생성여부를 확인합니다.

 

- 파이썬용 패키지 파일은 cv2.cp37-win_amd64.pyd 파일로 아래 두 폴더에 저장됩니다.(동일한 파일임) (파이썬 3.8버전으로 빌드한 경우 파일명 중간이 cp38로 바뀜)

    (opencv 빌드 폴더)\lib\python3

    (python 또는 anaconda 폴더)\lib\site-packages

 

기본 python 환경으로 구동할 경우 그대로 활용하시면 되고, 가상환경으로 사용하실 경우 아래와 같이 pyd 파일을 가상환경의 lib\site-packages 폴더로 복사하면 됩니다.  

 

만약 기존에 설치된 opencv-python(site-packages 내 cv2 폴더) 패키지가 있다면 충돌 방지를 위해 삭제하시는 것이 좋겠습니다.

 

 

 

5. python에서 opencv cuda 가속 설정


 

이제 python에서 cv2 패키지를 임포트하고 cuda 작동여부와 cuda 가속을 위한 코드를 테스트해봅니다.

 

import cv2
print(cv2.__version__)
count = cv2.cuda.getCudaEnabledDeviceCount()
print(count)

>> 4.5.0
    1

 

먼저 위의 코드와 같이 cv2를 임포트하고 cv2.cuda.getCudaEnabledDeviceCount() 함수를 실행하여 cuda 지원되는 장치가 있는 지 확인합니다. 일반적인 컴퓨터에는 그래픽카드가 1개가 설치되어 있으므로 1 이라고 뜨면 정상적으로 지원하는 것입니다.

 

 

net = cv2.dnn.readNet(path+"model/atron_yolov3_210127.weights", path+"custom/atron_yolov3_all.cfg", )

net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

 

그 다음으로 cv2.dnn.readnet() 등과 같이 딥러닝 모델을 적용할 때 cuda 가속을 지원하게 하려면 위의 코드와 같이 net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA), 그리고 net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) 두 줄을 추가하면 cuda 가속 전 보다 훨씬 빠르게 모델이 적용되는 것을 확인할 수 있습니다.