반응형

NDK를 지원하는 안드로이드 프로젝트를 생성한 후, OpenCV 라이브러리를 추가하여 사용하는 방법을 설명합니다. 

 

간단한 예제로 OpenCV Java API에서 캡처한 영상을 OpenCV C++ API에서 그레이스케일 영상으로 변환하고 다시  OpenCV Java API에서 화면에 보여줍니다. 



2016.11.20 : 최초 작성 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2019. 8. 8 

OpenCV 4.1.1를 위해 카메라 코드를 수정하고 android.support 대신에 androidx를 사용합니다. 

2020. 1. 19  OpenCV 4.2.0

2020. 6. 20 OpenCV 4.3.0, Android Studio 4.0, Android 10, NDK 21

2021. 1. 6  OpenCV 4.5.1, Android Studio 4.1.1, Android 11, NDK 21

2021. 4. 10  OpenCV 4.5.2, Android Studio 4.1.3, Android 11, NDK 21

2021. 9. 1 Android Studio 2020.3.1에서 OpenCV 모듈을 가져오려고 하면 위자드에서 Finish 버튼이 비활성화 상태로 유지되는 버그가 생긴듯합니다. 해결되기 전까진 수동으로 sdk 폴더를 안드로이드 프로젝트로 옮기고 build.gradle 파일을 수정해서 사용해야 하는 듯합니다.  자세한 내용은 https://stackoverflow.com/a/68738767 

2021. 10. 22 질문이 종종있어서 앞에서 언급했던 링크대로 포스트를 진행해보았습니다.
                      Android Studio Arctic Fox 2020.3.1 Patch 3

                      Android 11.0 API 30 

                      OpenCV 4.5.4

                      NDK 23.1 실제로는 하위 버전을 사용할 수도 있습니다.




1. 안드로이드 프로젝트 생성

2. 프로젝트에 OpenCV 라이브러리 추가

3. CMake 사용한 NDK + OpenCV 카메라 예제

4. 참고




1. 안드로이드 프로젝트 생성

 

1-1. Native C++를 선택합니다. 

 




1-2. Name 항목에 프로젝트 이름을 적고, Language는 Java,  Minimum API level은 API 21을 선택합니다.

 




1-3. 디폴트 값으로 두고 Finish 버튼을 클릭하면 됩니다.

 



2. 프로젝트에 OpenCV 라이브러리 추가

2-1. OpenCV를 위한 깃허브에서 opencv-4.5.4-android-sdk.zip 파일을 다운로드 합니다. 

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






압축을 풀어서 C:\에 복사해줍니다. 




2-2.  Android용 OpenCV가 다음 위치에 있는 것으로 가정하고 진행합니다.

C:\OpenCV-android-sdk

 




2-3.  현재는 이 방법은 진행하는데 문제가 있습니다. 문제가 수정될 때까지는  번거롭더라도 수동으로 모듈을 가져오는  2-4를 진행하세요. 참고 https://stackoverflow.com/a/68738767 



앞에서 진행한 프로젝트 생성이 완료되기를 대기합니다. 안드로이드 스튜디오의 상태 표시줄에 작업중 메시지가 사라져야 합니다. 

 

OpenCV 라이브러리 모듈을 프로젝트로 가져오기 위해 메뉴에서 File > New > Import Module를 선택합니다. 

 

Source directory 입력란 옆에 있는 버튼을 클릭합니다.

 



OpenCV-android-sdk 디렉토리 하위에 있는 sdk 디렉토리를 선택하고 OK 버튼을 클릭합니다. 

 




Finish 버튼을 클릭한 후 sync가 끝나길 대기합니다.

 




다음과 같이 NDK 21.1.6352462가 설치안되어 있다고 에러 메시지가 보이면  “Update NDK version to 22.1.7171670 and sync project”를 클릭하여 설치를 진행합니다. 

 

Failed to install the following SDK components:

    ndk;21.1.6352462 NDK (Side by side) 21.1.6352462

Install the missing components using the SDK manager in Android Studio.



Update NDK version to 22.1.7171670 and sync project




2-4. C:\OpenCV-android-sdk 에서 sdk 폴더를 복사합니다. 

 




앞에서 만든 안드로이드 프로젝트 폴더에 붙여넣기 합니다.

 




settings.gradle에 다음 한줄을 추가합니다.

 

include ':sdk'

 




상단에 보이는 Sync Now를 클릭합니다.

 



다음과 같은 에러가 발생합니다.

 

A problem occurred evaluating project ':sdk'.

> Plugin with id 'kotlin-android' not found.




build.gradle( Project)에 다음을 추가합니다.

 

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"

 

 




상단에 보이는 Try Again을 클릭합니다. 

 




2-5. app 모듈에서 opencv 라이브러리 모듈을 사용하도록 설정해줘야 합니다.

메뉴에서 File > Project structure를 선택한 후,  왼쪽에 보이는 리스트에서 Dependencies를 선택합니다. 

 




Modules에서  app을 선택한 후, Declared Dependencies에 보이는 +를 클릭하면 보이는 메뉴에서 Module Dependency를 선택합니다. 

 




앞에서 추가했던 opencv 모듈이 sdk 이름으로 보입니다. 체크한 후  OK버튼을 클릭합니다.

 




이제 sdk 모듈(opencv) app 모듈에서 사용할 수 있게 설정되었습니다. 

이제 OK 버튼을 클릭하여 Project Structure 창을 닫습니다.

 




2-6.  문제없이 sdk 모듈(opencv)이 추가되었다면 다음처럼 보입니다. 

 




3. CMake 사용한 NDK + OpenCV 카메라 예제

3-1.  안드로이드 스튜디오에서 CMake를 사용하여 C/C++ 코드를 컴파일 및 디버그하기 위해서는 다음 패키지가 필요합니다.

 

  • The Android Native Development Kit (NDK)

안드로이드에서 JAVA 코드와 C/C++ 코드를 같이 사용할 수 있게 해줍니다.

 

  • CMake



안드로이드 스튜디오 메뉴에서 Tools > SDK Manager를 선택합니다.



SDK Tools 탭에서  NDK, CMake를 선택하고 Apply 버튼을 클릭하면 다운로드 및 설치가 진행됩니다.

포스트 진행 과정에서 추가로 다른 버전의 NDK가 설치될 수 있습니다. 

 


Android 12.0은 설치되지 않고 Android 11.0이 설치된 상태에서 진행했습니다.

 



3-2. AppCompatActivity 클래스를 사용한 액티비티에서 타이틀바를 없애기 위해서 themes.xml 파일에 다음 코드를 추가합니다.

 




    <!-- Base application theme. -->
    <style name="Theme.UseOpenCVWithCMake" 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" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
        <!-- No Title Bar-->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
</resources>





3-3. 레이아웃 파일 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>





3-4. 매니페스트 파일 AndroidManifest.xml 에  다음 코드를 추가합니다. 

 



<?xml version="1.0" encoding="utf-8"?>

    package="com.tistory.webnautes.useopencvwithcmake">

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.front" android:required="false"/>
    <uses-feature android:name="android.hardware.camera.front.autofocus"  android:required="false"/>

    <supports-screens android:resizeable="true"
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:anyDensity="true" />
   
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.UseOpenCVWithCMake">
        <activity android:name=".MainActivity"
            android:screenOrientation="landscape"
            android:configChanges="keyboardHidden|orientation">




3-5. 카메라로부터 영상을 가져오는 것은 JAVA 코드에서 하며 JNI(Java Native Interface)를 사용하여 C/C++ 함수를 호출하여 영상처리를 진행합니다. 

 

자바코드 파일 MainActivity.java를 다음 코드로 대체합니다.

첫번째 줄에 있는 package는 남겨둬야 합니다. 

 

 

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();
    }


}




3-6. MainActivity.java 파일에 다음처럼 ConvertRGBtoGray 함수가 빨간색으로 보입니다. 

 




3-7. 마우스 커서를 ConvertRGBtoGray 함수에 가져가면 보이는 빨간전구를 클릭하고 메뉴에서 “Create JNO function for ConvertRGBtoGray”를 선택합니다.

 




native-lib.cpp를 선택합니다.

 




다음 코드를 참고하여 빨간색 부분을 제거하고 파란색 부분을 추가합니다.

 

#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>

using namespace cv;


extern "C" JNIEXPORT jstring JNICALL
Java_com_tistory_webnautes_useopencvwithcmake_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
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);
}




3-8.  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/webnautes/AndroidStudioProjects/UseOpenCVwithCMake) # 수정필요
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} )




3-9. Sync Now를 클릭하거나 메뉴에서 File > Sync Project with Gradle Files를 선택하여 Gradle build를 시작합니다.




빌드 후, 안드로이드 폰에 설치하여 실행시켜 보면  안드로이드폰의 방향에 따라  카메라 영상도 같이 회전합니다.  



스크린샷은 안드로이드 버전따라 차이가 있을 수 있습니다. 



참고

 

https://developer.android.com/ndk/guides/index.html

 

https://developer.android.com/studio/projects/add-native-code.html

 

https://github.com/googlesamples/android-ndk

 

http://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html

 

http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html



반응형

해본 것을 문서화하여 기록합니다.


포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
질문을 남겨주면 가능한 빨리 답변드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

">
  1. 이전 댓글 더보기
  2. thumbnail
    Favicon of https://opencv7example2.tistory.com BlogIcon 안스

    답장 감사드립니다!
    오류 메시지 입니다.
    Cannot resolve corresponding JNI function Java_com_example_opencv_1example_MainActivity_ConvertRGBtoGray. Could not find an existing file with JNI definitions in it. Please add a file with JNI definitions to the project in order to get suggestions. 분명 ConvertRGBtoGray 을 빨간전구를 눌러서 따라했음에도 불구하고, 7을 하고나면 다시 저렇게 뜹니다.. 그리고 동시에 왼쪽창에, com.example.opencv_example와 MainActivity에 빨간밑줄이 뜹니다..

  3. thumbnail
    Favicon of https://shjlee88.tistory.com BlogIcon StarvingDays

    웹나우테스 선생님
    ConvertRGBtoGray 함수 결과값으로 받아오는 스트링 값을 텍스트 뷰에 띄우고 싶습니다
    결과값을 메인 액티비티 클래스 바로 아래 선언한 private string 변수에다 반환하고 onCameraFrame 함수에 텍스트 뷰를 선언해서 스트링을 집어 넣으니 프로그램이 박살나버리네요
    이 작업을 어떤 함수 어떤 구간에다 해야할까요?

  4. thumbnail
    Favicon of https://skylain.tistory.com BlogIcon LSkyLain

    안녕하세요!
    웹나우테스 선생님 포스트들을 보며 OpenCV 활용하는 방법을 잘 배우고 있습니다.
    이번 포스트에서 OpenCV를 안드로이드 스튜디오에 sync하니, 이벤트로그에

    Gradle sync failed: com.android.tools.idea.gradle.project.sync.idea.issues.SdkPlatformNotFoundException: Module: 'sdk' platform 'android-26' not found. (4 s 991 ms)

    포스트와는 다르게 이런 식으로 실패메시지가 뜨는데 무시해도 되는부분인가요??

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.11 21:38 신고

      sdk manager에서 android 26을 설치하세요. 찾을수 없다는 에러입니다

    • thumbnail
      Favicon of https://skylain.tistory.com BlogIcon LSkyLain
      2021.04.11 22:39 신고

      헐 빠른 답변 너무 감사합니다. 덕분에 포스팅 제대로 완수했습니다! 그리고, 혹시 여기에다 다른 포스트에 올리신 OpenPose를 이용한 손가락인식도 적용시킬수 있나요??

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.11 22:51 신고

      OpenPose 안드로이드용을 찾으면 가능합니다.

  5. thumbnail
    Favicon of https://ddd66.tistory.com BlogIcon dfd666

    선생님 위에 예제 그대로 따라해서 Sync Project with Gradle Files를 선택하여 Gradle build까지 성공을 했는데 실행시켜보면
    C:\Users\dbswn\AndroidStudioProjects\last\app\src\main\cpp\CMakeLists.txt : C/C++ debug|x86 : CMake Error at C:\Users\dbswn\AndroidStudioProjects\last\app\src\main\cpp\CMakeLists.txt:23 (add_library):
    Cannot find source file:

    C:/Users/webnautes/AndroidStudioProjects/last/app/src/main/cpp/native-lib.cpp

    Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
    .hxx .in .txx
    이렇게 오류가 뜹니다. 원인이 뭘까요 ? 답변해주시면 정말 감사하겠습니다

  6. thumbnail
    Favicon of https://data-view.tistory.com BlogIcon 샤른호스트

    천천히 따라해보고 있는데요,

    MainActivity.java 에서 ConvertRGBtoGray 가 빨간색으로 오류가 난다고 하셨는데 저는 오히려 ConvertRGBtoGray는 괜찮고 setVisibility가 빨갛게 되어서 그 뒷부분을 못해보고 있네요....뭐가 문제일지 아실런지요?

  7. thumbnail
    Favicon of https://skylain.tistory.com BlogIcon LSkyLain

    선생님 이 포스트대로 하면 OpenCV에서 따로 빠지는 기능없이 다 연동되는건가요?

    https://webnautes.tistory.com/1268 이 포스트랑은 OpenCV 연동하는 방법이 달라서 여쭤봅니다!

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.19 17:37 신고

      네 맞습니다

    • thumbnail
      Favicon of https://skylain.tistory.com BlogIcon LSkyLain
      2021.04.19 22:07 신고

      감사합니다! 그리고 포스트 마지막에

      빌드 후, 안드로이드 폰에 설치하여 실행시켜 보면 안드로이드폰의 방향에 따라 카메라 영상도 같이 회전한다 라고 하셨는데 저는 실행시키면 가로모드 고정이되는데 어떤 부분을 손봐야할까요? rotate나 landscape 다 손대봐도 안되네요 ㅠ

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.19 22:09 신고

      가로모드는 어쩔수 없는 부분입니다. 보는 사람입장에서 카메라가 회전되는 것 처럼 보이는 겁니다.

  8. thumbnail
    Favicon of https://longlong.tistory.com BlogIcon _롱롱

    안녕하세요, 좋은 포스트 감사드립니다.
    제가 똑같이 따라한 것 같은데,
    native-lib.cpp에서

    #include <jni.h>
    #include <C:\OpenCV-android-sdk\sdk\native\jni\include\opencv2\opencv.hpp>
    using namespace cv;

    using namespace cv;의 cv 부분에 오류가 납니다.
    또한,
    MainActivity.java에서

    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {

    this 부분에서 오류가 납니다.
    조언해주실 부분이 있을까요? 읽어주셔서 감사합니다ㅠ

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.25 19:06 신고

      CMakeLists.txt에서 프로젝트 경로를 확인해보세요. 최근에 촤신버전으로 작성한거라 버전차이로 문제는 안생길듯합니다.

    • thumbnail
      Favicon of https://longlong.tistory.com BlogIcon _롱롱
      2021.04.26 17:32 신고

      헉 경로 바꾼다고 바꿨었는데 잘못 썼었네요.. 경로바꾸니까 cv오류 부분은 사라졌습니다!! 감사합니다ㅠ
      근데 this부분은 그대로 오류가 나네요ㅠ
      마우스를 갖다 대어보면 다음과 같이 뜹니다.
      Required type:Context
      Provided:MainActivity
      이 부분은 혹시 어떻게 해야 하는지 아시나요??

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.26 19:17 신고

      혹시 자바 코드 수정했나요? 아니라면 API를 30으로 해보세요

    • thumbnail
      Favicon of https://longlong.tistory.com BlogIcon _롱롱
      2021.04.26 20:28 신고

      API를 30으로 해서 처음부터 다시 해봤는데 같은 오류가 뜨네요..ㅠㅠ

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.04.26 20:40 신고

      전 오류가 안나는데 이상하군요. 정확한 에러메시지를 복사하여 구글에서 원인을 찾아야할거 같습니다

    • thumbnail
      Favicon of https://longlong.tistory.com BlogIcon _롱롱
      2021.04.28 20:08 신고

      webnautes님, 선생님께서 쓰신 다른 포스트 따라해 보다가 오류가 나서
      SDK Platform들을 API level 21에서 30까지 모조리 다운 받았는데
      뭔가 되는 것 같길래
      이 포스트도 다시 해보니 작동이 잘 됩니다.
      최근에 완전 초기화를 시켜서 이 부분을 다시 다운 받아볼 생각을 전혀 하지 못했었네요!!
      좋은 포스트와 답변 감사드립니다. 기분 좋은 저녁 되세요!!

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.05.03 22:06 신고

      해결되었다니 다행입니다~~

  9. thumbnail
    2021.05.04 01:48

    비밀댓글입니다

  10. thumbnail
    2021.05.17 03:28

    비밀댓글입니다

  11. thumbnail
    Favicon of https://study-education.tistory.com BlogIcon 오늘도간다

    제 경우는 native-lib.cpp 파일에 문제가 있는것 같습니다.

    #include <opencv2/opencv.hpp> include 오류가 있는것 같구요..

    Mat 도 붉은색 표시가 되고, COLOR_RGBA2GRAY 도 붉은색 표시가 됩니다.

    어떻게 해야 할까요?

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.05.18 19:38 신고

      다시 차근차근 해보세요. 여러번 확인한거라 문서에는 문제가 없습니다. 혹 안드로이드 스튜디오에서 처리중인데 진행해서 문제가 될수도 있습니다

  12. thumbnail
    Favicon of https://skylain.tistory.com BlogIcon LSkyLain

    항상 감사드립니다.

    제가 저장해놓은 이미지 100장 정도를 안드로이드 카메라에 잡히는 화면과 비교해서 조건에 부합하면 그 화면을 캡쳐하는 코드를 짜려하는데,
    이미지를 /sdk/native/jni/include/opencv2/imgproc 이 경로에 넣어놓는게 맞을까요? 아니라면 어디에 넣어야하는지 여쭙고 싶습니다...

    그리고 캡쳐하는 알고리즘은 VideoCapture 함수를 이용하려하는데 native-lib에서 잘 작동하는지 조언을 구할 수 있을까요?

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.05.26 18:51 신고

      assets 폴더에 이미지를 넣으면 됩니다. 안드로이드에서 읽어오는 방법은 구글에서 검색해보면 많이 나올겁니다. 안드로이드에서 카메라캡쳐는 본 포스트에서 사용한 방법을 써야 합니다.

    • thumbnail
      Favicon of https://skylain.tistory.com BlogIcon LSkyLain
      2021.05.28 15:10 신고

      감사합니다!

      말씀대로 assets폴더를 만들고 폴더에 넣어놓은 이미지를 불러오는데 성공했습니다!

      다만 자동캡쳐가 안돼서 아쉬운데 이건 따로 알고리즘이 생각날랑 말랑해서 어떻게든 될듯 합니다. 항상 감사드립니다 ㅠㅠ

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.05.28 15:29 신고

      잘하셨네요. 자동 캡쳐라함은 이미지을 불러온경우 카메라에서 찍은 이미지와 비교하는 건가요?

    • thumbnail
      Favicon of https://skylain.tistory.com BlogIcon LSkyLain
      2021.05.28 16:02 신고

      네네. 카메라에서 찍은 실시간 처리되는 이미지를 assets폴더에 있는 이미지들과 비교하여, 조건에 부합하면, 카메라에서 찍고있는 이미지를 VideoCapture로 캡쳐하는 방식을 생각하였는데 웹캠이 아니고 앱이라 그런지 안되더라구요..

      그래서 약간 방식을 바꾸어서 assets폴더에 있는 이미지와 matResult를 비교하는 방식으로 바꿔 볼 생각입니다!

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.05.28 16:30 신고

      자바용 OpenCV에서 영상캡쳐한걸 cpp코드로 넘겨주고 cpp코드에서 이미지가 일치하는게 있는지 체크하여 리턴해주면 자바코드에서 해당 이미지를 파일로 저장하면 될듯합니다.

  13. thumbnail
    Favicon of https://manwha.tistory.com BlogIcon manwha

    안녕하세요 OpenCV의 경우 Preview는 1920x1080(화면사이즈)로 제한되는 것 같습니다.
    저는 4k(3840x2160) 이미지로 영상처리를 진행하고 싶은데,
    Preview를 4k로 변경하거나, Capture시 4k 이미지를 얻는 방법이 있을까요?
    폰의 카메라는 4000x3000까지 해상도를 지원합니다.
    항상 좋은 정보 올려주셔서 감사합니다.

  14. thumbnail
    Favicon of https://nyanguk.tistory.com BlogIcon nyanguk

    안녕하세요!! 따라하던 도중 터치를 입력받아 두 좌표로 선을 그리고자 하는데 circle,ractangle 함수는 모두 실행되는데 line 함수 실행시 자꾸 해당함수를 위한 레퍼런스를 찾지 못했다고 합니다....ㅜㅠ 혹시 도움을 받을 수 있을까요,,,,?


    오류내용
    Build command failed.
    Error while executing process C:\Users\lobgd\AppData\Local\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C C:\Users\lobgd\AndroidStudioProjects\hanstyle\app\.cxx\cmake\debug\arm64-v8a native-lib}
    ninja: Entering directory `C:\Users\lobgd\AndroidStudioProjects\hanstyle\app\.cxx\cmake\debug\arm64-v8a'
    [1/1] Linking CXX shared library C:\Users\lobgd\AndroidStudioProjects\hanstyle\app\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so
    FAILED: C:/Users/lobgd/AndroidStudioProjects/hanstyle/app/build/intermediates/cmake/debug/obj/arm64-v8a/libnative-lib.so
    cmd.exe /C "cd . && C:\Users\lobgd\AppData\Local\Android\Sdk\ndk\21.1.6352462\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android26 --gcc-toolchain=C:/Users/lobgd/AppData/Local/Android/Sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=C:/Users/lobgd/AppData/Local/Android/Sdk/ndk/21.1.6352462/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -std=gnu++11 -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libnative-lib.so -o C:\Users\lobgd\AndroidStudioProjects\hanstyle\app\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/native-lib.cpp.o C:/Users/lobgd/AndroidStudioProjects/hanstyle/sdk/native/libs/arm64-v8a/libopencv_java4.so -llog -latomic -lm && cd ."
    CMakeFiles/native-lib.dir/native-lib.cpp.o: In function `Java_com_hanstyle_image_activity_CreateWizet_drawImg_1processing':
    C:/Users/lobgd/AndroidStudioProjects/hanstyle/app/src/main/cpp/native-lib.cpp:64: undefined reference to `cv::line(cv::_InputOutputArray const&, cv::Point_<float>, cv::Point_<int>, cv::Scalar_<double> const&, int, int, int)'
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.


    나의 코드
    extern "C"
    JNIEXPORT void JNICALL
    Java_com_hanstyle_image_activity_CreateWizet_drawImg_1processing(JNIEnv *env, jobject thiz,
    jlong output_image, jint sx,
    jint sy, jint fx, jint fy) {
    Mat &img_output = *(Mat *) output_image;
    const Scalar white = Scalar(255);
    // rectangle(img_output, Rect(sx*2, sy*2, 150,150), Scalar(255, 0, 255), 20, 20, 0);
    //line(img_output, Point(sx, sy), Point(fx, fy), white, 5, 8, 0);
    line(img_output, Point(sx, sy), Point(fx, fy), Scalar(255, 0, 255), 5, 8, 0);
    }

    //

  15. thumbnail
    2021.06.22 17:39

    비밀댓글입니다

  16. thumbnail
    Favicon of https://overthename.tistory.com BlogIcon _DAMI_

    선생님 mainactivty.java파일에서
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this)
    이문장에 this가 계속 오류가 뜨는데 어떻게 해야할까요?

  17. thumbnail
    Favicon of https://overthename.tistory.com BlogIcon _DAMI_

    안드로이드 스튜디오 버전이 4.2.2인것빼곤 opencv도 최신에 깔아서 똑같습니다
    change 1st parameter of method 'BaseLoaderCallback'from 'Context' to 'MainActivity'라고 빨간전구 클릭시 뜹니다.
    버전 문제인건가요? ...

  18. thumbnail
    Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222

    안녕하세요~
    우분투 18.04, 안드로이드 스튜디오 2020.3.1.22 에서 프로젝트를 진행하고 있는데 2-4 에서 sdk 폴더를 선택하면 Specify location of the Gradle or Android Eclipse project 라는 경고문이 뜨면서 Cancel을 제외한 버튼 모두가 활성화되지 않습니다.. 이런 경우 어떻게 해야하나요??

  19. thumbnail
    Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222

    감사합니다! 방금 전의 오류는 해결이 됐지만 이번에는 Finish 버튼이 활성화되지 않습니다......

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.08.28 17:46 신고

      하다가 꼬일수 있습니다. 프로젝트 새로 만들어서 다시 해보세요.

    • thumbnail
      Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222
      2021.08.28 19:25 신고

      계속 같은 문제가 발생하네요.. 문제가 무엇인지 모르겠습니다 모듈 네임에도 :sdk를 적어두었는데 계속해서 finish 버튼이 활성화되지 않습니다. 재부팅도 해보았습니다.

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.08.28 19:28 신고

      제가 마지막에 포스트 업데이트할때 사용한 버전들과 차이 있는게 뭔지 확인해보세요

    • thumbnail
      Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222
      2021.08.28 19:48 신고

      android studio를 새로 설치해보았더니 되었습니다ㅜㅜ 친절하게 답변해주셔서 정말 감사합니다. 다른 프로젝트에서도 많이 참고하고 있습니다! 유익한 글 항상 감사드립니다.

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.08.28 19:49 신고

      다행이네요^^

    • thumbnail
      Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222
      2021.08.31 22:19 신고

      안녕하세요 자꾸 번거롭게 해드려서 죄송합니다ㅜㅜ
      3-5 에서 onCreate 안의 setVisibility 메소드에서 Cannot resolve method 'setVisibility' in 'CameraBridgeViewBase' 이런 오류가 발생합니다. 해결할 수 있는 방법이 있을까요?

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.08.31 23:03 신고

      아래 링크를 확인해보세요

      https://kim-hoya.tistory.com/45

    • thumbnail
      2021.08.31 23:21

      비밀댓글입니다

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.08.31 23:23 신고

      환경문제라 프로젝트로 해결될거 같지는 않습니다.

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.08.31 23:24 신고

      포스트와 차이나는 버전이 뭐가 있나요?

    • thumbnail
      Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222
      2021.09.01 15:23 신고

      opencv는 4.5.2를 사용하고 android studio는 4.1.1을 사용하고 있습니다!
      버전 차이는 없는 것 같습니다

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.09.01 22:10 신고

      현재 안드로이드 스튜디오에서 OpenCV를 모듈로 가져오려고 하면 Finish 버튼이 활성화 안되는 버그가 있는듯합니다. 어찌 해결하셨던거 같은데 완전한 해결방법이 아닌듯 보입니다.

      아래 링크에 보면 수동으로 모듈을 안드로이드 프로젝트로 복사하여 사용해야 한다고 하는데 코틀린을 기준으로 되어있네요.

      https://stackoverflow.com/a/68738767

    • thumbnail
      Favicon of https://hyunisland.tistory.com BlogIcon ekgus2222
      2021.09.02 17:36 신고

      stackoverflow의 방법으로 해도 오류가 계속 발생했는데 https://www.youtube.com/watch?v=rKvIKkBefJQ
      이 유튜브를 참고해서
      '
      private CameraBridgeViewBase mOpenCvCameraView;


      mOpenCvCameraView = (CameraBridgeViewBase)findViewById(R.id.activity_surface_view);
      mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
      mOpenCvCameraView.setCvCameraViewListener(this); CameraBridgeViewBase
      '
      이 부분을
      mOpenCvCameraView를 CameraBridgeViewBase가 아닌 JavaCameraView로 변경했더니 setVisibility에 빨간줄이 그어지는 현상은 해결했습니다!
      opencv 버전은 3.4.2를 사용했는데 해결 이유와 webnautes님이 올리신 이 프로젝트와 합쳐서 사용해도 되는 지는 모르겠습니다

      친절하게 해결방안을 찾아주셔서 감사합니다!

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.09.02 17:43 신고

      버전이 올라가면서 바뀐부분으로 알고있는데 동작하면 다행이네요. 안드로이드 스튜디오 예전버전을 설치해서 해결하는게 나을듯 보입니다

  20. thumbnail
    2021.09.25 23:34

    비밀댓글입니다

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.09.25 23:38 신고

      다음 포스트를 참고하여 시작해보세요

      TCP 소켓을 사용하여 웹캠의 이미지를 송수신하는 서버/클라이언트 예제

      https://webnautes.tistory.com/1382

  21. thumbnail
    Favicon of https://remminme.tistory.com BlogIcon rem min

    안녕하세요 선생님, 좋은 글 감사합니다.
    다름이 아니라
    make project를 하면
    <html>Google Play requires that apps target API level 29 or higher.
    라고 뜨는데 어떻게 하면될까요?? sdk version 을 올리면 되려나요? 제가 알기로는 29 이상으로 해버리면 카메라를 받을 때 권한을 받아야된다고 해서 코드를 약간 다르게 해야되다고 들었었는데,targetSdkVersion 을 올려도 상관없으려나요?

    아래와 같이 error: cannot find -lnative-lib 라고 뜨기도 합니다.

    > Task :app:buildCMakeDebug FAILED
    C/C++: ninja: Entering directory `C:\Users\MindsLab\AndroidStudioProjects\OpenCVNativeDemo\app\.cxx\Debug\621e4e69\armeabi-v7a'
    C/C++: C:/Users/MindsLab/AppData/Local/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lnative-lib
    C/C++: clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    C/C++: C:/Users/MindsLab/AppData/Local/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lnative-lib

    또 다른 오류는 ninja.exe 에 대한 이야기가 나오는데 어떤것이 문제인지 모르겠습니다..ㅠㅠ
    Build command failed.
    Error while executing process C:\Users\MindsLab\AppData\Local\Android\Sdk\cmake\3.10.2.4988404\bin\ninja.exe with arguments {-C C:\Users\MindsLab\AndroidStudioProjects\OpenCVNativeDemo\app\.cxx\Debug\621e4e69\armeabi-v7a opencvnativedemo}
    ninja: Entering directory `C:\Users\MindsLab\AndroidStudioProjects\OpenCVNativeDemo\app\.cxx\Debug\621e4e69\armeabi-v7a'
    [1/2] Building CXX object CMakeFiles/opencvnativedemo.dir/native-lib.cpp.o
    [2/2] Linking CXX shared library C:\Users\MindsLab\AndroidStudioProjects\OpenCVNativeDemo\app\build\intermediates\cxx\Debug\621e4e69\obj\armeabi-v7a\libopencvnativedemo.so
    FAILED: C:/Users/MindsLab/AndroidStudioProjects/OpenCVNativeDemo/app/build/intermediates/cxx/Debug/621e4e69/obj/armeabi-v7a/libopencvnativedemo.so
    cmd.exe /C "cd . && C:\Users\MindsLab\AppData\Local\Android\Sdk\ndk\20.1.5948944\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=armv7-none-linux-androideabi21 --gcc-toolchain=C:/Users/MindsLab/AppData/Local/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64 --sysroot=C:/Users/MindsLab/AppData/Local/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -march=armv7-a -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -Wl,-z,noexecstack -shared -Wl,-soname,libopencvnativedemo.so -o C:\Users\MindsLab\AndroidStudioProjects\OpenCVNativeDemo\app\build\intermediates\cxx\Debug\621e4e69\obj\armeabi-v7a\libopencvnativedemo.so CMakeFiles/opencvnativedemo.dir/native-lib.cpp.o -lnative-lib C:/Users/MindsLab/AndroidStudioProjects/OpenCVNativeDemo/sdk/native/libs/armeabi-v7a/libopencv_java4.so -llog -latomic -lm && cd ."
    C:/Users/MindsLab/AppData/Local/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/windows-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin\ld: error: cannot find -lnative-lib
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

    • thumbnail
      Favicon of https://webnautes.tistory.com BlogIcon webnautes
      2021.10.20 17:17 신고

      정확히 기억나지는 않는데 포스트에서 테스트에 사용한 버전인 안드로이드11이 api 30일겁니다. 버전을 올려보세요.

      포스트와 똑같이하면 잘 동작하나 우선해보고 변경하세요