brunch

You can make anything
by writing

C.S.Lewis

by 서준수 Jun 03. 2019

안드로이드 OpenCV 사용하기

Canny Edge Detector

OpenCV는 이미지 프로세싱을 하기에 너무 좋은 라이브러리이다. 이러한 OpenCV를 NDK를 이용하여 안드로이드에서도 사용할 수 있다. 어떻게 사용하는지 프로젝트 생성부터 예제까지 실행하는 과정을 살펴보자.


<목표>

1. NDK를 사용할 수 있는 프로젝트 설정

2. Canny Edge 검출 예제 실행

   2.1 JNI 사용

   2.2 OpenCV Java API 사용


<개발 환경>

윈도우 10

안드로이드 스튜디오 3.4.1


NDK를 사용하기 위한 SDK Tool이 설치되어 있는지 확인하고 없으면 설치하도록 한다.

필요한 패키지는 LLDB, CMake, NDK이다.


필요한 Tool 설치 확인


<프로젝트 생성>

안드로이드 스튜디오(버전 3.4.1 기준)에 JNI를 사용할 수 있도록 설정된 Empty Activity를 가지는 프로젝트를 만들 수 있는 메뉴가 있다.


JNI를 사용할 수 있는 Native C++ 프로젝트 선택


Native C++ 메뉴를 선택하고 프로젝트명 정도만 바꾸고 나머지는 기본 설정으로 Next로 쭉 진행해서 완료한다.


cpp 폴더 생성


설정이 완료되면 새롭게 프로젝트가 만들어진다. 그러면 일반적인 프로젝트와 다르게 cpp 폴더가 존재하는 것을 확인할 수 있다.


<OpenCV 라이브러리 추가>

사용할 OpenCV 라이브러리를 다음 링크에서 다운로드한다. 이 프로젝트에서 사용할 버전은 opencv-4.1.0-android-sdk.zip이다.

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

OpenCV 다운로드


OpenCV 라이브러리는 추후 경로 지정이 필요하다. 따라서 혼란을 방지하기 위해서 다운로드한 파일은 다음 경로에 압축을 푼다. (C:\OpenCV-android-sdk)


C:OpenCV-android-sdk


다운로드한 OpenCV 라이브러리를 프로젝트에서 사용하기 위해서 Import 시켜야 한다.

다음과 같이 File > New > Import Module 메뉴를 선택한다.


모듈 import 하기


Source directory 경로는 앞서 OpenCV 라이브러리 압축을 풀어놨던 C:\OpenCV-android-sdk내의 sdk 폴더를 선택한다. 즉 C:\OpenCV-android-sdk\sdk가 된다.


C:OpenCV-android-sdksdk


폴더 선택을 하면 Module name을 지정할 수 있다. :opencv로 변경한다.


모듈명 변경


Import 한 opencv 모듈은 app 모듈에 Dependencies를 설정해야 한다.

File > Project Structure를 선택한다.



Project Structure 창이 뜨면 Dependencies를 선택한 후 app을 선택한다. 그리고 우측 Declared Dependencies에서 + 아이콘을 누른 후 Module Dependency를 선택한다.



그러면 아래와 같이 앞서 추가한 opencv 모듈이 보일 것이다. 선택한 후 OK를 누른다.



opencv 모듈이 정상적으로 추가되면 다음과 같이 보인다.



여기까지 진행했다면 설정은 이상으로 끝이다.


<OpenCV를 사용한 Canny Edge Detection 예제>

예제 소스는 부분적으로 첨부파일로 공유한다.

package 경로 등은 변경이 필요하다. 필요한 부분만 복사해서 사용하는 것도 방법이다.

AndroidManifest는 다음과 같이 permission 설정이 필요하다. 사진 파일을 불러오기 위해서다.


JNI를 통해서 native-lib.cpp에 있는 함수를 호출할 수 있도록 해야 한다.

ImageActivity.java에서 다음과 같이 native 함수를 선언하면 다음과 같이 에러가 발생한다.

해결하기 위해서는 먼저 느낌표 아이콘을 눌러서 첫 번째를 선택해서 native 함수를 만들어준다. 그러면 다음과 같이 native-lib.cpp에 함수가 생성이 된다.



해당 함수에 Canny Edge Detection을 위해서 TODO 아래에 다음과 같은 코드를 추가한다.


Mat &inputMat = *(Mat *) inputImage;
Mat &outputMat = *(Mat *) outputImage;

cvtColor(inputMat, outputMat, COLOR_RGB2GRAY);
Canny(outputMat, outputMat, th1, th2);



하지만 native-lib.cpp에서 include 부분을 보면 아직까지 opencv.hpp 파일을 인식하지 못하여 빨간색으로 표시된다. 이 문제를 해결하기 위해서 CMakeLists.txt 파일을 수정해야 한다.

이 부분은 경로 설정하는 부분이 많다. 본인 환경에 맞는 경로를 하나라도 제대로 설정하지 않으면 에러가 발생한다.

pathPROJECT 부분은 현재 프로젝트 경로를 설정한다.

pathOPENCV 부분은 프로젝트로 import 했던 opencv 모듈 경로를 설정한다.

pathLIBOPENCV_JAVA 부분은 pathOPENCV 내에 native/lib 경로를 추가한다.

(경로만 제대로 설정해준다면 모듈이 꼭 import 된 위치에 있지 않아도 된다. 예를 들어 pathOPENCV는 C드라이브에 압축을 풀어놓았던 C:\OpenCV-android-sdk\sdk로 설정해도 된다. )


target_link_libraries에 다음과 같이 lib_open를 추가한다.



정상적으로 설정이 완료되면 native-lib.cpp에서 빨간색으로 보이던 에러들이 사라진다.


이제 빌드 후 실행하면 된다. 먼저 저장소 권한 동의를 한다.

그 후 LOAD IMAGE 버튼을 선택하면 갤러리가 호출된다. 갤러리에서 Edge 검출을 하고자 하는 이미지를 선택하면 다음과 같이 선택한 이미지와 Edge 검출이 된 이미지가 함께 표시된다.


여기까지는 JNI를 사용한 방법이다. ImageActivity.java를 보면 다음과 같이 두 함수가 있다. 현재 사용된 함수는 detectEdgeUsingJNI()이다. 해당 함수를 보면 detectEdgeJNI()라는 native 함수를 호출하고 있는 것을 볼 수 있다. 


OpenCV Java API를 사용하는 방법detectEdge() 함수와 같다. 결과는 당연히 둘 다 동일하다.



실행화면


ref.)

NDK 프로젝트 생성 : https://webnautes.tistory.com/1054?category=704164

Canny Edge OpenCV Java API 사용법 : https://kkokkal.tistory.com/1329


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari