일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
- gitcommit정보
- OpenCV
- AmazonDynamoDB
- AWS
- 대학생
- 컴활필기
- gitcommit정보확인
- 컴활필기두음썜
- DynamoDBExamples
- dynamodb
- androidStudio
- android
- GitHub
- gitpush
- golang
- gitpull
- 개발
- git파일정보확인
- git명령어
- 안드로이드opencv
- 메모장에있던필기개발일지에옮긴것
- DynamoDBGolang
- 수제비
- 안드로이드스튜디오
- androidstudioopencv
- 안드로이드
- 개발일지
- 안드로이드스튜디오opencv
- Today
- Total
주섬주섬 개발일지
Android Studio NDK 지원 OpenCV 라이브러리 사용 방법 본문
⬛ 패키지 설치
Tools > SDK Manager >NDK, CMake 패키지 선택 후 OK
![](https://blog.kakaocdn.net/dn/cqKBDk/btsEhzP4WXe/Uic2rSnsalIkz43o83MEJk/img.png)
⬛ 안드로이드 프로젝트 생성
New Project > Native C++ 선택
![](https://blog.kakaocdn.net/dn/cQUpMf/btsEdJsLWJw/OpHX3NcbcwCmucQ8YeaECk/img.png)
프로젝트명 기입, Language: Java, Minimum SDK: API 21 (없을 시 Tools에서 설치)
![](https://blog.kakaocdn.net/dn/xBoLP/btsEiTtExVt/CAtwzMbOWbgG2c5BVgSGP0/img.png)
C++ Standard Default, Finish 버튼 클릭
![](https://blog.kakaocdn.net/dn/bSxp5S/btsEdIAEjYA/JoqYzTO8ShK3v9KoeZ5cck/img.png)
⬛ 프로젝트에 OpenCV 라이브러리 추가
OpenCV 깃허브 저장소에서 opencv-4.7.0-android-sdk.zip 설치 후 압축 해제
https://github.com/opencv/opencv/releases
Releases · opencv/opencv
Open Source Computer Vision Library. Contribute to opencv/opencv development by creating an account on GitHub.
github.com
![](https://blog.kakaocdn.net/dn/cEEUYY/btsEdXj28OW/WGw5F91XZgkbbzJyTYBBd0/img.png)
- Android Studio에 라이브러리 모듈 Import
File > New > Import Module 에서 OpenCV-android-sdk 디렉토리 하위에 있는 sdk 디렉토리 선택 후 OK
![](https://blog.kakaocdn.net/dn/bKctfu/btsEb7U8WJn/sZg0DxdyAUQY09jN5ipw91/img.png)
SDK 모듈이 추가되었다면 다음과 같이 확인할 수 있음.
![](https://blog.kakaocdn.net/dn/23SA9/btsEiiUJGM3/PgjfdKL5gi2XiexuCzxb1K/img.png)
sdk > build.gradle에서 apply plugin: 'kotlin-android 제거
![](https://blog.kakaocdn.net/dn/bJmC3t/btsEiypBXGL/I29sdginkpA8NyaBkzlDKK/img.png)
2. App 모듈에서 OpenCV 라이브러리 모듈 사용할 수 있도록 설정
File > Project structure 에서 Dependencies > + 버튼 클릭 > 3. Moduile Dependency
![](https://blog.kakaocdn.net/dn/Ffism/btsEctcHn7Y/0KD2WEkBYOeKMmej0E013K/img.png)
sdk 체크 후 OK > 아래 사진처럼 sdk가 추가됨.
![](https://blog.kakaocdn.net/dn/bC04Ch/btsEeJZ8VeT/dtB90k7b16Sl1kchUQ2VzK/img.png)
⬛ CMake 사용한 NDK와 OpenCV로 카메라 작동 및 라이브러리 사용
카메라를 사용하기 위해서 manifests>AndroidManifest.xml에 permission을 추가해야함.
![](https://blog.kakaocdn.net/dn/carYJJ/btsEdSJTIOH/JQXk98qGvvl8mHYzqKbzK0/img.png)
레이아웃 파일 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<org.opencv.android.JavaCameraView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/activity_surface_view" />
</LinearLayout>
타이틀 바 제거 themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Opencvtest2" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
<!-- No Title Bar-->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
java 코드에서 JNI(Java Native Interface) 사용하여 C++ 함수를 호출하여 영상 처리 진행
MainActivity.java
package com.example.opencvtest;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import java.util.Collections;
import java.util.List;
import static android.Manifest.permission.CAMERA;
public class MainActivity extends AppCompatActivity
implements CameraBridgeViewBase.CvCameraViewListener2 {
private static final String TAG = "opencv";
private Mat matInput;
private Mat matResult;
private CameraBridgeViewBase mOpenCvCameraView;
public native void ConvertRGBtoGray(long matAddrInput, long matAddrResult);
static {
System.loadLibrary("opencv_java4");
System.loadLibrary("native-lib");
}
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
mOpenCvCameraView = (CameraBridgeViewBase)findViewById(R.id.activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
mOpenCvCameraView.setCameraIndex(0); // front-camera(1), back-camera(0)
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "onResume :: Internal OpenCV library not found.");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_2_0, this, mLoaderCallback);
} else {
Log.d(TAG, "onResum :: OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onCameraViewStarted(int width, int height) {
}
@Override
public void onCameraViewStopped() {
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
matInput = inputFrame.rgba();
if ( matResult == null )
matResult = new Mat(matInput.rows(), matInput.cols(), matInput.type());
ConvertRGBtoGray(matInput.getNativeObjAddr(), matResult.getNativeObjAddr());
return matResult;
}
protected List<? extends CameraBridgeViewBase> getCameraViewList() {
return Collections.singletonList(mOpenCvCameraView);
}
private static final int CAMERA_PERMISSION_REQUEST_CODE = 200;
protected void onCameraPermissionGranted() {
List<? extends CameraBridgeViewBase> cameraViews = getCameraViewList();
if (cameraViews == null) {
return;
}
for (CameraBridgeViewBase cameraBridgeViewBase: cameraViews) {
if (cameraBridgeViewBase != null) {
cameraBridgeViewBase.setCameraPermissionGranted();
}
}
}
@Override
protected void onStart() {
super.onStart();
boolean havePermission = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
havePermission = false;
}
}
if (havePermission) {
onCameraPermissionGranted();
}
}
@Override
@TargetApi(Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onCameraPermissionGranted();
}else{
showDialogForPermission("앱을 실행하려면 퍼미션을 허가하셔야합니다.");
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@TargetApi(Build.VERSION_CODES.M)
private void showDialogForPermission(String msg) {
AlertDialog.Builder builder = new AlertDialog.Builder( MainActivity.this);
builder.setTitle("알림");
builder.setMessage(msg);
builder.setCancelable(false);
builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id){
requestPermissions(new String[]{CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
}
});
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
});
builder.create().show();
}
}
MainActivity.java 파일에 ConvertRGBtoGray 함수가 빨간색으로 보이는데, 마우스 커서를 가져가면 보이는 빨간 전구를 클릭하고 메뉴에서 “Create JNI function for ConvertRGBtoGray” > “native-lib.cpp” 선택
native-lib.cpp
#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C"
JNIEXPORT void JNICALL
Java_com_tistory_webnautes_useopencvwithcmake_MainActivity_ConvertRGBtoGray(JNIEnv *env,
jobject thiz,
jlong mat_addr_input,
jlong mat_addr_result) {
// TODO: implement ConvertRGBtoGray()
Mat &matInput = *(Mat *)mat_addr_input;
Mat &matResult = *(Mat *)mat_addr_result;
cvtColor(matInput, matResult, COLOR_RGBA2GRAY);
}
CMakeLists.txt를 다음 코드로 대체 (pathPROJECT 경로를 실제 프로젝트 경로로 변경해야함)
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
set(pathPROJECT C:/Users/user/AndroidStudioProjects/opencvtest) # 수정필요
set(pathOPENCV ${pathPROJECT}/sdk)
set(pathLIBOPENCV_JAVA ${pathOPENCV}/native/libs/${ANDROID_ABI}/libopencv_java4.so)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
include_directories(${pathOPENCV}/native/jni/include)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${pathPROJECT}/app/src/main/cpp/native-lib.cpp )
add_library( lib_opencv SHARED IMPORTED )
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${pathLIBOPENCV_JAVA})
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
lib_opencv
# Links the target library to the log library
# included in the NDK.
${log-lib} )
Sync Now 클릭 혹은 메뉴 > File > Sync Project with Gradle Files > Gradle build
'Programing > Android Studio' 카테고리의 다른 글
Android Studio .so 파일 생성 및 사용하기 (0) | 2024.02.01 |
---|