Austin's_Lab

[I.MX6Q] Opencv Porting on I.MX6Q (ARM based board) 본문

Embedded System

[I.MX6Q] Opencv Porting on I.MX6Q (ARM based board)

Ausome_(Austin_is_Awesome) 2017. 5. 1. 22:58

Embedded System이라는 수업에서 Arm based embedded board를 활용한 Term project로 얼굴 표정인식을 진행하기로 했다. 얼굴 표정 인식은 아무래도 deep-learning을 활용해야하지 싶다. 실습용 embedded board로는 아무래도 deep-learning을 수행하기엔 무리가 있으므로 학습기는 내 PC(서버)에 올리는 것으로 하고, arm board에서는 실시간 얼굴 검출 및 서버로 전송을 하는 역할만 주기로 했다. 외에 인식된 내용을 바탕으로 board에서 해야할 일이 더 있지만 이번 포스팅에서는 논외이므로 바로 본론으로 들어간다.


Arm board에서 얼굴 검출을 하기위해 여러 방법을 찾던 중, opencv에서 Haar feature를 이용한 얼굴 검출 알고리즘을 지원한다는 것을 알고 Arm board에 opencv porting을 진행하기로 결정했다. Board는 Huins사의 Achro-I.MX6Q 보드이다. 


대충 스펙을 보자면  

Coretex-A9 / Quad core, NEON지원(per Core), 256KB~1MB L2 Cache, VFPvd16 Trustzone, 32KB I/D Cache per Core, 3D graphics, Two 2D graphics engines, Vector Graphics Hardware Accelerator, 64bit DDR3, 2-channel 32bit LPDDR2 at 533MHz, CSI(카메라), HDMI IPC, UART, SATA, USB, PCI, FlexCAN, Ethernet 등 외에도 수많은 기능을 제공하며 웬만한 시스템은 이 machine에서 구현이 가능한 것 같다. 웬만한 건 다 구현이 가능한 것 같은데... Cross compile은 잘 안 됐다. 결론적으로 성공은 했지만 너무 많은 시간이 소모됐다.


일단 첫째로 가장 중요한 cross compiler는 Huins사에서 제공한 toolchain을 사용했다. 따라서 toolchain을 만드는 것은 따로 다루지 않는다.


Toolchain까지 준비가 됐다면 이제 arm borad에 porting할 opencv가 필요할 것이다. 나는 ubuntu 12.04에서 opencv-2.4.13 version(2017.05.01 기준)을 썼다

.

*- 이제부터 쓸 작업들은 수 많은 실패들 가운데 50번 가까이 패키지들과 opencv를 재설치하면서 수행한 작업들이기 때문에 꼭 필요하진 않은 게 있을 수도 있다. -*


일단 관련 패키지를 깔아야 한다.

$ sudo apt-get install build-essential    -필수 뭔 지 자세히는 모르지만 필수..

$ sudo apt-get install cmake    -필수 opencv 설치에 쓰임

$ sudo apt-get install git    -필수 repo 받아오는 데 쓰임

$ sudo apt-get install cmake-curses-gui    -없어도 되지만 있으면 편함

$ sudo apt-get install libpng12-dev    -밑으로 opencv 관련 패키지들

$ sudo apt-get install libjpeg62-dev

$ sudo apt-get install libtiff4-dev

$ sudo apt-get install zlib1g-dev

$ sudo apt-get install autoconf automake libtool autotools-dev    - 얘들은 솔직히 뭐에 필요한 건지 모르겠다.


아래 네 개는 내가 arm-none-linux-gnueabi를 쓰기 때문에 필요없다고 생각했었는데 나중에 꼭 필요한 존재가 된다.

$ sudo apt-get install g++-arm-linux-gnueabi 

$ sudo apt-get install gcc-arm-linux-gnueabi

$ sudo apt-get install g++-arm-linux-gnueabihf

$ sudo apt-get install gcc-arm-linux-gnueabihf


다 설치했으면 이제 opencv 소스를 받으면 된다. 소스를 받기 전에 opencv building을 위한 디렉토리를 만든다.

$ mkdir opencv && cd opencv

$ git clone https://github.com/Itseez/opencv.git    -이 명령어는 최신버전(3.2)이 받아질 것이다. 2.4를 원하면 master말고 2.4로 받아야함.


이제 본격적으로 시작이다. 아마 본 포스트를 따라해도 잘 안 될 것이다.

arm cross compile용 cmake configuration을 해주어야 한다. /opencv/opencv-2.4.13/platforms/linux에 들어가보면 arm-gnueabi.toolchain.cmake라는 파일이 있을 것이다. 2.4.13.2버전이나 3.2버전 같은 경우에는 파일이 4개가 있었다. 하나씩 다 열어보고 코드를 보면서 아래 나온 것과 비슷한 게 나오면 똑같이 맞춰준다.


$ arm-none-linux-gnueabi-gcc --version

$ arm-none-linux-gnueabi-g++ --version

두 코드를 실행하여 arm용 gcc의 버전을 확인한다. 내 경우 4.8.3이었다.


이제 /opencv-2.4.13/platforms/linux/arm-gnueabi.toolchain.cmake를 열어서 동일한 코드를 찾아 밑줄 친 부분을 본인 시스템에 맞게 고쳐준다.

set(GCC_COMPILER_VERSION "4.8.3" CHCHE STRING "GCC Compiler version")

set(CMAKE_C_COMPILER  /opt/toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-gcc)

set(CMAKE_CXX_COMPILER  /opt/toolchains/arm-2014.05/bin/arm-none-linux-gnueabi-g++)

set(ARM_LINUX_SYSROOT  /opt/toolchains/arm-2014.05/arm-none-linux-gnueabi${FLOAT_ABI_SUFFIX} CACHE PATH "Arm cross compilation system root")

set(CMAKE_C_FLAGS  "-mcpu=cortex-a9 -O3"  CACHE STRING "c flags")

set(CMAKE_AR  "/opt/toolchains/arm-2014.05/arm-none-linux-gnueabi-ar")


다음 build를 실행할 디렉토리를 만들고 그 곳에서 cmake를 실행한다.

$ mkdir ~/opencv/build && cd ~/opencv/build

$ cmake -DCMAKE_INSTALL_PREFIX=/opt/toolchains/arm-2014.05/opencv -DSOFTFT=ON -DCMAKE_TOOLCHAIN_FILE=../opencv-2.4.13/platforms/linux/arm-gnueabi.toolchain.cmake ../opencv-2.4.13

$ ccmake .    <- 실행하면 뭔가 리스트가 쭉 나온다. 거기서 아래 있는 내용들을 다 OFF해준다. enter치면 바뀐다.

BUILD_TESTS

WITH_1394

WITH_CUDA

WITH_EIGEN

WITH_FFMPEG

WITH_GSTREAMER

WITH_GTK

WITH_JASPER

WITH_JPEG

WITH_OPENEXR

WITH_PNG

WITH_PVAPI

WITH_QT

WITH_QT_OPENGL

WITH_TBB

WITH_TIFF

WITH_UNICAP

WITH_V4L

WITH_XINE


어떤 블로그에서는 이 중 꽤 많은 애들을 ON으로 설정 주고 cmake하는 곳이 많았다. 아마 보드 사양이나 사용처에 따라 다르지 않을까 싶다. IMX.6Q에서는 필요 없어 보인다. 아직까지는... 아직은 얘네 없이 필요한 건 다 잘 돌아가고 있다. 얘들 설정을 바꿔주고, c와 g를 차례대로 눌러 새 configuration을 generate해준다.


여기서부터 아마 잘 안 될 것이다.

$ sudo make   

make를 진행하면 버전이 다르다는 오류, 무슨 경로를 못 찾는다는 오류, 필요없는 설정을 해줬다는 warning 등등 피말리게 할 것이다. 웬만한 문제는 위의 configuration을 잘 따라했으면 해결됐겠지만 그래도 해결이 안 된 것은 구글링 해보면 잘 나와있다. 

버전이 다르다는 문제에 대해서만 한 번 살펴보자. 

~/opencv/opencv-2.4.13/cmake/OpenCVPackaging.cmake 파일의 버전을 ~/opencv/opencv-2.4.13/modules/core/include/opencv2/core/version.hpp의 버전과 맞춰주어야 한다.

set(OPENCV_VCSVERSION "2.4.13") 을 ~/opencv/opencv-2.4.13/cmake/OpenCVPackaging.cmake 안에 적절한 위치에 넣어준다.

make가 성공했으면 install을 진행한다.

$ sudo make install

이 때도 역시 오류가 발생할 수 있다. 갑자기 zlib관련한 파일들을 못 찾아버렸다. arm-gnueabi.toolchain.cmake 파일에서 set(ARM_LINUX_SYSROOT ...) 부분이 제대로 설정이 돼 있는 지 확인해본다. set(CMAKE_AR="....) 이 부분이 문제였던 것 같기도 하다. cmake 할 때 -DSOFTFT=ON 설정을 해주었는 지도 확인해본다.


install까지 성공했으면 이제 생성된 파일들을 arm board에 올리면 된다.include랑 lib 디렉토리에 있는 애들만 올리면 되는 것 같다. 하지만 나는 haar mask를 써야하므로 share 디렉토리도 함께 옮겼다. USB로 옮기는 데 옮기는 과정에서 lib 디렉토리의 심볼릭 링크 파일들은 USB로 옮겨지지 않았다. 얘네는 본 파일만 옮기고 같은 이름으로 arm board에서 따로 심볼릭 링크를 만들어주면 된다.


host PC에서 opencv를 이용한 프로그램을 cross compile하고 arm board에서 돌려보면 GLIBCXX_3.4.15 어쩌고 하는 오류가 난다.

마지막 관문이다. 이 때 아까 필요 없다고 생각했는데 꼭 필요한 존재였다는 gcc-arm-linux-gnueabi가 필요하다. 실행과정에서 문제가 된 파일은 libstdc++.so.6이라는 파일인데 얘가 GLIBCXX_3.4.15 버전이 필요한가 보다. 근데 확인해보면 얘는 2.몇 버전을 갖고 있었다. 찾아보니 host machine에서 GLIBCXX_3.이상을 가진 libstdc++.so.6 파일을 그대로 target board에 옮겨주면 된다고 한다. 바로 이 파일이 /usr/arm-linux-gnueabi/lib/hf 디렉토리에 들어있다. sudo apt-get 명령어를 통해 받는 것은 64bit intel processor버전이므로 arm board와 호환이 안 될 것이다. 반드시 arm-linux-gnueabi를 설치해서 이 곳에 있는 libstdc++.so.6.16(본 파일)을 옮겨 libstdc++.so.6이라는 이름으로 심볼릭 링크를 만들어준다.


그럼 이제 모든 문제가 해결되었다. 만약 컴파일이 안 되거나 실행이 안 된다면 

PATH나 LD_LIBRARY_PATH 혹은 PKG_CONFIG_PATH를 알맞는 경로로 export 해주면 될 것이다.


### 혹시 잘 안 돼서 다시 설치해야한다면 아래 명령어를 실행하고 처음부터 다시 시작해본다... Good Luck

$ sudo apt-get purge libopencv-*


Comments