Information/Vision

[OpenCV] Ubuntu에서 local에 OpenCV를 설치하고 C++에서 사용하는 방법

페트론 2020. 9. 18. 11:24
해당 게시물을 참고하러 오시는 분들이 많으신 것 같습니다.
로컬에서 환경을 조작해 문제를 해결할 수도 있겠지만,
Docker를 이용하여 환경에 구애받지 않고 OpenCV 및 ROS를 사용하시는 것을 권장드립니다.
ROS나 OpenCV도 어려운데 Docker까지 하시려면 부담이 될 수 있겠지만,
앞으로는 Docker Container를 이용한 개발이 필수가 될 것이라 생각되니, 
천천히라도 익혀보시길 권장드리겠습니다.

 

Ubuntu에서 OpenCV를 설치하는 경우, 보통 시스템 폴더 안 (ex. usr/local/include) 에 설치되게 된다.

만약 다른 버전의 OpenCV를 설치하고자 하는 경우 시스템 폴더 안의 OpenCV를 삭제하고 다시 설치하게 되는 경우가 많은데,

이런 경우 제대로 OpenCV 제거 및 설치하기가 쉽지 않다.

 

또한 프로그램마다 필요로 하는 OpenCV 버전이 다를 수 도 있기 때문에, local 저장공간에 다른 버전의 OpenCV를 설치하고 이를 해당 프로그램에서 사용할 수 있다면 매우 편리할 것이다. 

 

아래 링크를 참조하면 자세한 내용을 확인할 수 있다.

 

https://www.learnopencv.com/install-opencv-3-4-4-on-ubuntu-16-04/

 

Install OpenCV 3.4.4 on Ubuntu 16.04 (C++ and Python)

OpenCV released OpenCV-3.4.4 and OpenCV-4.0.0 on 20th November. There have been a lot of bug fixes and other changes in these versions. The release highlights are as follows: OpenCV is now C++11 library and requires C++11-compliant compiler. Minimum requir

www.learnopencv.com

 

# Issue

문제가 발생했다. 필자의 개발 환경에는 Ubuntu 16.04 LTS에 ROS Kinetic이 설치되어 있다.

이 때문에 OpenCV를 링크할 때에 ROS에 설치된 OpenCV인 OpenCV 3.3.1-dev 버전으로 적용되는 것이다.

(아무리 다르게 환경설정을 해도)

 

이를 해결하기 위해 순차적으로 실험을 진행해보겠다. 

작업순서는 다음과 같다.

 

1. opencv version test용 catkin workspace 만들기

 

$ cd ~

$ mkdir catkin_ws_opencv_version

$ cd catkin_ws_opencv_version

$ mkdir src

$ cd src

$ catkin_init_workspace

$ catkin_create_pkg opencv_version_test roscpp

$ cd opencv_version_test

$ cd ~/catkin_ws_opencv_version

$ catkin build

$ source devel/setup.bash

2. test 용 cpp 파일 만들기

 

$ cd ~/catkin_ws_opencv_version/src/opencv_version_test/src
$ nano opencv_version_test.cpp

링크를 참조하면 아래와 같은 코드를 통해 OpenCV version을 cpp 프로그램 내에서 확인할 수 있다.

일단 빌드만 해보기 위해 opencv 관련문구는 주석처리를 한다.

또한 ros로 돌려야 하기 때문에 노드 초기화도 해주어야 한다.

#include <ros/ros.h>
#include <iostream>
//#include "opencv2/opencv.hpp"

int main(int argc, char** argv) {

	ros::init(argc, argv, "opencv_version_test");
	ros::NodeHandle nh;
	//std::cout << "OpenCV version : " << CV_VERSION << std::endl;
 
	return 0;
}

3. CMakeLists.txt 수정

 

이제 CMakeLists.txt를 다음과 같이 수정할 것이다.

cmake_minimum_required(VERSION 2.8.3)
project(opencv_version_test)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

find_package(catkin REQUIRED COMPONENTS roscpp)

catkin_package()

include_directories(${catkin_INCLUDE_DIRS})

add_executable(opencv_version_test src/opencv_version_test.cpp)
target_link_libraries(opencv_version_test ${catkin_LIBRARIES})

 

기본적인 내용만 남겨두고, opencv_version_test.cpp 파일을 이용해 opencv_version_test 노드를 생성한다.

c++11 컴파일러는 차후에 사용할 가능성이 있기 때문에 주석처리만 하여 남겨주었다.

 

주의할 사항은 catkin_package 처럼 아무 내용이 없더라도 넣어주어야 에러가 나지 않는다는 것이다.


4. Build 해보기

이제 아래내용으로 빌드를 해보면 잘 되는 것을 확인할 수 있다.

$ cd ~/catkin_ws_opencv_version

$ catkin build

5. CMakeLists.txt 및 opencv_version_test.cpp 수정

이제 CMakeLists.txt와 opencv_version_test.cpp를 수정하여 빌드해보자.

참고로 현재 필자의 OpenCV 설치 상태는 개판이다.

ROS의 opencv-3.3.1-dev도 설치되어 있고, usr/local에도 추가적으로 opencv-4.5.0-pre를 설치했고,

local에도 opencv-3.4.4와 opencv-4.5.0-pre가 설치되어있다.

이러한 상황에서 어떤 opencv를 가장 먼저 load하는지 확인해보자.

 

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(opencv_version_test)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

find_package(catkin REQUIRED COMPONENTS roscpp)
find_package(OpenCV REQUIRED)

catkin_package()

include_directories(${catkin_INCLUDE_DIRS})

add_executable(opencv_version_test src/opencv_version_test.cpp)
target_link_libraries(opencv_version_test ${catkin_LIBRARIES} ${OpenCV_LIBS})

 

opencv_version_test.cpp

#include <ros/ros.h>
#include <iostream>
#include "opencv2/opencv.hpp"

int main(int argc, char** argv) {

	ros::init(argc, argv, "opencv_version_test");
	ros::NodeHandle nh;
	std::cout << "OpenCV version : " << CV_VERSION << std::endl;
 
	return 0;
}

 

Build

$ ~/catkin_ws_opencv_version

$ catkin build

 

Run

// terminal_1
$ roscore

// terminal_2
$ rosrun opencv_version_test opencv_version_test

 

그러면 다음과 같은 결과를 확인할 수 있다.

eh420@eh420-Strix-GL704GW-GL704GW:~/catkin_ws_opencv_version$ rosrun opencv_version_test opencv_version_test
OpenCV version : 3.3.1-dev

 

OpenCV 3.3.1-dev은 ROS에 설치되어있는 OpenCV version이며, 디폴트로 ROS의 OpenCV를 load 한다는 것을 알 수 있다.


6. local에 설치된 OpenCV 4 설정

 

이번엔 local에 있는 OpenCV4가 적용되는지 확인해보겠다.

참조한 링크는 다음과 같다.

 

Install OpenCV 4 on Ubuntu 16.04 (C++ and Python)

 

Install OpenCV 4 on Ubuntu 16.04 (C++ and Python)

OpenCV released OpenCV-3.4.4 and OpenCV-4.0.0 on 20th November. There have been a lot of bug fixes and other changes in these versions. The release highlights are as follows: OpenCV is now C++11 library and requires C++11-compliant compiler. Minimum requir

www.learnopencv.com

 

CMakeLists.txt

cmake_minimum_required(VERSION 3.1)
project(opencv_version_test)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

set(OpenCV_DIR /home/eh420/installation/OpenCV-master/lib/cmake/opencv4)

find_package(catkin REQUIRED COMPONENTS roscpp)
find_package(OpenCV REQUIRED)

catkin_package()

include_directories(${catkin_INCLUDE_DIRS})

add_executable(opencv_version_test src/opencv_version_test.cpp)
target_link_libraries(opencv_version_test ${catkin_LIBRARIES} ${OpenCV_LIBS})

 

Build

$ ~/catkin_ws_opencv_version

$ catkin build

 

Run

// terminal_1
$ roscore

// terminal_2
$ rosrun opencv_version_test opencv_version_test

 

그러면 다음과 같은 결과를 확인할 수 있다.

eh420@eh420-Strix-GL704GW-GL704GW:~/catkin_ws_opencv_version$ rosrun opencv_version_test opencv_version_test
OpenCV version : 4.5.0-pre

 

OpenCV 4.5.0-pre 가 제대로 불러와진 것이다.


7. cv_bridge를 사용하는 경우

cv_bridge는 OpenCV의 이미지 데이터 포맷과 ROS Image 데이터 포맷간의 변환을 위한 패키지이다.

문제는 cv_bridge는 기본적으로 ROS에 설치되어 있는 OpenCV version을 이용한다는 것이다. 

이 문제 때문에 cv_bridge와 local에 설치한 OpenCV를 함께 사용하기는 매우 어렵다.

해당 문제에 관한 내용은 다음 링크를 참조한다.

 

Solve the compatibility notes of cv_bridge in ROS Kinetic and installing OpenCV 2.4.xx by yourself in Ubuntu environment

 

解决Ubuntu环境下ROS Kinetic中的cv_bridge和自己安装OpenCV 2.4.xx兼容性笔记_bigdog_1027的博客-CSDN博客

我们如果使用的ROS版本为Kinetic,那么ROS一般会默认安装OpenCV3。所以使用cv_bridge的情况下,ROS会自动去调用它自己安装的OpenCV3。但是对于一部分人还是比较习惯使用OpenCV2,所以需要对CMakeLists.txt�

blog.csdn.net

해당 문제를 확인하기 위해 다음과 같이 파일들을 수정하여 실행해보자.

 

package.xml

<?xml version="1.0"?>
<package format="2">
  <name>opencv_version_test</name>
  <version>0.0.0</version>
  <description>The opencv_version_test package</description>

  <maintainer email="eh420@todo.todo">eh420</maintainer>

  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>cv_bridge</build_depend>

  <exec_depend>roscpp</exec_depend>
  <exec_depend>cv_bridge</exec_depend>

  <export>

  </export>
</package>

 

CMakeLists.txt

 

cmake_minimum_required(VERSION 3.1)
project(opencv_version_test)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

set(OpenCV_DIR /usr/local/lib/cmake/opencv4)

find_package(catkin REQUIRED COMPONENTS roscpp cv_bridge)
find_package(OpenCV REQUIRED)

catkin_package(  
  CATKIN_DEPENDS 
  roscpp
  cv_bridge
)

include_directories(${catkin_INCLUDE_DIRS})

add_executable(opencv_version_test src/opencv_version_test.cpp)
target_link_libraries(opencv_version_test ${catkin_LIBRARIES} ${OpenCV_LIBS})

 

Build

$ ~/catkin_ws_opencv_version

$ catkin build

 

Run

// terminal_1
$ roscore

// terminal_2
$ rosrun opencv_version_test opencv_version_test

 

그러면 다음과 같은 결과를 확인할 수 있다.

eh420@eh420-Strix-GL704GW-GL704GW:~/catkin_ws_opencv_version$ rosrun opencv_version_test opencv_version_test
OpenCV version : 3.3.1-dev

 

OpenCV 4.5.0-pre 를 무시하고 cv_bridge에서 사용하는 OpenCV 3.3.1-dev 가 불러와진 것이다.

 

그렇기 때문에 위의 블로그를 참조하여 수정해주는 작업이 필요하다.


8. cv_bridge 수정

먼저 아래 명령어를 통해 cv_bridge config 파일을 켠다.

$ cd /opt/ros/kinetic/share/cv_bridge/cmake/

$ sudo gedit cv_bridgeConfig.cmake

 

이 후에 다음 구문들을 수정해준다. 이 때, 본인의 OpenCV 경로에 맞추어주면 된다.

cv_bridgeConfig.cmake

include 부분에 자신이 설치한 opencv의 경로를 입력한다.

# default include setting
#if(NOT "include;/opt/ros/kinetic/include/opencv-3.3.1-dev;/opt/ros/kinetic/include/opencv-3.3.1-dev/opencv " STREQUAL " ")
#  set(cv_bridge_INCLUDE_DIRS "")
#  set(_include_dirs "include;/opt/ros/kinetic/include/opencv-3.3.1-dev;/opt/ros/kinetic/include/opencv-3.3.1-dev/opencv")

# OpenCV 4.5.0-pre include setting
if(NOT "include;/usr/local/include/opencv4/opencv2;/usr/local/include/opencv4; " STREQUAL " ")
  set(cv_bridge_INCLUDE_DIRS "")
  set(_include_dirs "include;/usr/local/include/opencv4/opencv2;/usr/local/include/opencv4;")

cv_bridgeConfig.cmake

libraries 부분에는 자신이 사용할 라이브러리를 추가해준다.

# default libraries setting
#set(libraries "cv_bridge;/opt/ros/kinetic/lib/x86_64-linux-gnu/libopencv_core3.so.3.3.1;/opt/ros/kinetic/lib/x86_64-linux-gnu/libopencv_imgproc3.so.3.3.1;/opt/ros/kinetic/lib/x86_64-linux-gnu/libopencv_imgcodecs3.so.3.3.1")

# OpenCV 4.5.0-pre libraries setting
set(libraries "cv_bridge;/usr/local/lib/libopencv_core.so.4.5.0;/usr/local/lib/libopencv_imgproc.so.4.5.0;/usr/local/lib/libopencv_imgcodecs.so.4.5.0;/usr/local/lib/libopencv_highgui.so.4.5.0;/usr/local/lib/libopencv_features2d.so.4.5.0;/usr/local/lib/libopencv_xfeatures2d.so.4.5.0;/usr/local/lib/libopencv_stitching.so.4.5.0;")

 

CMakeLists.txt

이 부분에서 중요한 점은 cv_bridge 만을 활성화 시키고 나머지 OpenCV 관련 내용은 비활성화 시키는 것이다.

이미 cv_bridge에서 내가 필요한 내용은 모두 가져오기 때문에, 다른 작업을 할 필요가 없는 것이다.

cmake_minimum_required(VERSION 3.1)
project(opencv_version_test)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

#set(OpenCV_DIR /usr/local/lib/cmake/opencv4)

find_package(catkin REQUIRED COMPONENTS roscpp cv_bridge)
#find_package(OpenCV REQUIRED)

catkin_package(  
  CATKIN_DEPENDS 
  roscpp
  cv_bridge
)

include_directories(${catkin_INCLUDE_DIRS})

add_executable(opencv_version_test src/opencv_version_test.cpp)
#target_link_libraries(opencv_version_test ${catkin_LIBRARIES} ${OpenCV_LIBS})
target_link_libraries(opencv_version_test ${catkin_LIBRARIES})

 

Build

$ ~/catkin_ws_opencv_version

$ catkin build

 

Run

// terminal_1
$ roscore

// terminal_2
$ rosrun opencv_version_test opencv_version_test

 

그러면 다음과 같은 결과를 확인할 수 있다.

eh420@eh420-Strix-GL704GW-GL704GW:~/catkin_ws_opencv_version$ rosrun opencv_version_test opencv_version_test
OpenCV version : 4.5.0-pre

9. custom library와 사용하는 경우?

보통 OpenCV를 사용하는 custom library의 경우 CMakeLists.txt에서 다음과 같이 명시하게 된다.

add_library(custom_lib src/custom_library.cpp )

target_link_libraries(custom_lib ${OpenCV_LIBRARIES})

 

하지만 cv_bridge를 통해 이미 OpenCV 라이브러리가 빌드 되었으므로, 아래 구문으로 만들면 된다.

add_library(custom_lib src/custom_library.cpp )

target_link_libraries(custom_lib ${catkin_LIBRARIES})
반응형