반응형

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




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


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


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


4. 참고




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

 

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

 




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

 




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

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

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






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




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

C:\OpenCV-android-sdk

 




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

 

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. app 모듈에서 opencv 라이브러리 모듈을 사용하도록 설정해줘야 합니다.

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

 




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

 




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

 




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

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

 




2-5.  문제없이 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가 설치될 수 있습니다. 

 




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

 

 

 <!-- No Title Bar-->

        <item name="windowActionBar">false</item>

        <item name="windowNoTitle">true</item>

 

 

    <!-- Base application theme. -->

    <style name="Theme.UseOpenCVWithNdkbuild" 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 에  다음 코드를 추가합니다. 

 



(1)

    <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" />

 

(2)  이 부분은 기존 코드를 대체해야 합니다.

 

        <activity android:name=".MainActivity"

            android:screenOrientation="landscape"

            android:configChanges="keyboardHidden|orientation">



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

 

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


    <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.UseOpenCVWithNdkbuild">

        <activity android:name=".MainActivity"

            android:screenOrientation="landscape"

            android:configChanges="keyboardHidden|orientation">


            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>


</manifest>




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 ConvertR”를 선택합니다.

 




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

 

 

#include <jni.h>

#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);

}

 

 

 

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. 메뉴에서 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. 방문객 2020.07.31 03:06

    정말 친절한 설명 감사합니다.

  3. jyshin 2020.08.26 17:33

    위 예제에서.. native-lib.cpp을 Visual Studio에서 빌드 후 .so 로 만들어서 현재 Android Studio 프로젝트의 CMakeList.txt 에 추가했을 경우, 현재 Android Studio가 사용중인 SDK API level하고 NDK 버전이 다르다면 빌드시 오류 발생하나요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.08.26 18:12 신고

      비주얼 스튜디오에서 리눅스 Arm용으로 so 파일을 만들었나요?

  4. jyshin 2020.08.28 20:09

    비주얼 스튜디오에서 리눅스 Arm용으로 so 파일을 만들었나요?
    답변) 아니요. visual studio 2019 pro 버전 이용자입니다. VS 2019는 android dynamic 라이브러리 생성 프로젝트 기능이 있어서.. VS 의 Android 라이브러리 생성 기능으로 .so를 만들었습니다.
    Sdk 와 ndk 버전이 android studio 의 프로젝트 보다는 하위버전이었는데.. 이게 원인일까요?

  5. Favicon of https://hwangchan.tistory.com BlogIcon HwangChan 2020.09.24 10:47 신고

    저...빌드 도중에
    Unexpected native build target opencv_jni_shared. Valid values are: native-lib
    이런 에러가 뜨는데 build.gradle(;sdk)쪽에서 확인 했는데 어떻게 해결해야 할지 모르겠네요..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.09.24 10:52 신고

      cpp 파일이름을 opencv_jni_shared로 바꾸어서 문제 생긴듯합니다. native-lib로 사용해야합니다.

    • Favicon of https://hwangchan.tistory.com BlogIcon HwangChan 2020.09.24 11:14 신고

      그 빌드와 설치는 잘되었는데 앱을 실행 시키면 강제종료가 됩니다..혹시 왜그러는지 아시나요..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.09.24 12:41 신고

      로그캣에서 원인을 찾아야 합니다. 포스트와 차이나는 부분을 검토해야 할듯합니다. 포스트 코드는 여러번 검증했습니다.

    • Favicon of https://hwangchan.tistory.com BlogIcon HwangChan 2020.09.24 14:36 신고

      2020-09-24 14:28:11.802 17058-17058/? E/Zygote: isWhitelistProcess - Process is Whitelisted
      2020-09-24 14:28:11.807 17058-17058/? E/Zygote: accessInfo : 1
      2020-09-24 14:28:11.839 17058-17058/? E/example.camera: Unknown bits set in runtime_flags: 0x8000
      2020-09-24 14:28:12.058 17058-17058/com.example.camera3 E/AndroidRuntime: FATAL EXCEPTION: main
      Process: com.example.camera3, PID: 17058
      java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
      at java.lang.Runtime.loadLibrary0(Runtime.java:1071)
      at java.lang.Runtime.loadLibrary0(Runtime.java:1007)
      at java.lang.System.loadLibrary(System.java:1667)
      at com.example.camera3.MainActivity.<clinit>(MainActivity.java:39)
      at java.lang.Class.newInstance(Native Method)
      at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
      at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
      at android.app.Instrumentation.newActivity(Instrumentation.java:1251)
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3436)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3707)
      at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
      at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
      at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2220)
      at android.os.Handler.dispatchMessage(Handler.java:107)
      at android.os.Looper.loop(Looper.java:237)
      at android.app.ActivityThread.main(ActivityThread.java:8016)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1076)
      로그캣 확인 결과인데 LoadLibrary쪽에서 오류가 뜬거같습니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.09.24 20:48 신고

      다음 에러가 문제 인듯합니다.
      java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found

      아래 링크의 답변을 참고하면
      https://www.366service.com/jp/qa/c99576c8dd71930bfe63deaeda9bd986

      다음 한줄을 CMakeLists.txt에 추가하면 해결된다는데 테스트는 못해봤습니다.

      include(ndk-stl-config.cmake)

      위 링크에 가보면 어디에 삽입해야 하는지 보여주는 링크가 있습니다. '

  6. Favicon of https://dhpark1212.tistory.com BlogIcon EastHoon 2020.11.17 21:27 신고

    조금 아쉬운 부분은 있네요.

    복사하는 코드가 어떤 내용을 담고 있는지 조금더 설명이 있으면 좋을 것 같습니다.

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2020.11.17 21:44 신고

      좋은 의견 감사합니다. 다음번 업데이트시 반영하도록 하겠습니다

  7. Favicon of https://dhpark1212.tistory.com BlogIcon EastHoon 2020.11.17 22:19 신고

    처음에 C:\OpenCV-android-sdk\sdk 파일 선택했을 때 Finish 버튼 활성화 안됬었는데

    프로젝트 지우고 다시 선택하니 활성화가 됬습니다.

    이건 왜 그런 거죠??

  8. Favicon of https://50billion-dollars.tistory.com BlogIcon 로구상 2021.01.05 03:49 신고

    실행은 아무 이상없이 되는데, 혹시 인식이 어떻게 진행되는 건가요?
    그냥 카메라 화면만 나오고, 인식이 안 되는 것 같습니다.

  9. Favicon of https://lolou.tistory.com BlogIcon 의도_ 2021.01.06 21:00 신고

    안녕하세요, BaseLoaderCallback 클래스에서
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.DialogInterface.OnClickListener;
    import android.util.Log;
    이 부분을 임포트 해 오지 못하여서 오류가 나고 있어요
    왜그런걸까요??

    run을 돌려보면

    C:\Users\leebbr\AndroidStudioProjects\OpenCVCamera\app\src\main\cpp\CMakeLists.txt : C/C++ debug|arm64-v8a : CMake Error at C:\Users\leebbr\AndroidStudioProjects\OpenCVCamera\app\src\main\cpp\CMakeLists.txt:23 (add_library):
    Cannot find source file:

    C:/Users/webnautes/AndroidStudioProjects/OpenCVCamera/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

    이런식으로 에러가 찍혀요..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.06 22:19 신고

      좀 더 확인이 필요하겠지만 에러를 보니 CMakeLists.txt에서 프로젝트 위치를 잘못수정하신듯합니다. webnautes라고 적힌부분이 leebbr이 되어야 할거 같네요

  10. Favicon of https://phj9908.tistory.com BlogIcon pasongsong 2021.01.07 16:26 신고

    항상 감사합니다
    opencv 4.4
    안드로이드 스튜디오 gradle 4.1.1
    ndk 22
    로 하면 native 함수가 JNI로 변환이 안되고(빨간색 전구에 안뜨더라고요..)
    gradle을 3.5.1로 변경해야 JNI함수로 변경가능 하던데 ndk 21.1.6352462를 추가로 설치하면 해결되는 것인가요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.07 16:59 신고

      네 맞습니다. 제가 빨간글씨로 표시한 폴더가 제대로 생성되었나 꼭 확인해보세요

  11. Favicon of https://lolou.tistory.com BlogIcon 의도_ 2021.01.11 14:34 신고

    안녕하세요, 제가 응용을 해서 버튼별로 화면의 색을 바꿔주는 것까지 응용을 하였고요,
    이제 추가로 촬영 버튼을 누르면 저장이 되게 구현하고 싶은데 https://webnautes.tistory.com/1087의 3번을 참고해서 동일하게 구현했더니,
    버튼(화면의 색을 바꿔주는버튼이나 촬영버튼 )들을 누르면 2021-01-11 14:26:34.133 2158-2158/com.leebbr.opencvcamera D/JavaCameraView: Preview Frame received. Frame size: 3110400
    이것만 계속 로그캣에 찍히면서 화면이 버튼눌렀을 때의 화면만 보여지고 멈춘 후에 렉이 걸려버려요..
    어느부분 때문에 그런걸까요..

  12. 2021.01.11 14:52

    비밀댓글입니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.11 18:37 신고

      코드만 봐서는 원인을 찾기 힘듭니다. 디버깅을 시도해보거나 코드를 단계별로 실행해서 원인을 찾아야 할거 같삽니다.

  13. Favicon of https://lolou.tistory.com BlogIcon 의도_ 2021.01.11 22:46 신고

    답변 주셔서 항상감사드려요:)
    제가 초보라,, 촬영버튼 눌렀을 때 저장되는 것 때문에 너무 힘드네요ㅠㅠ
    boolean ret = Imgcodecs.imwrite( filename, matResult);
    if ( ret ) Log.d(TAG, "SUCESS");
    else Log.d(TAG, "FAIL");

    여기서 ret이 계속 FAIL로 로그가 찍혀서 저장이 안되는건가 해요.. (추측일뿐)
    어디를 어떻게 수정하면 될지 알려주실 수 있을까요?ㅠㅠㅠ
    matResult : Mat [ 1080*1920*CV_8UC4, isCont=true, isSubmat=false, nativeObj=0x6fab6c6140, dataAddr=0x6f35200000 ]
    matResult 값을 이용해서 뭘 하면 될것같기도 한데... 도저히 감이 안와요ㅠㅠ

    그리고 이게 저장이 되면 갤러리에 저장이 되는건가요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.11 23:51 신고

      다음 포스트의 코드를 썼는데 안된경우라면
      https://webnautes.tistory.com/1087

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.11 23:53 신고

      안드로이드 10.0에서 발생하는 퍼미션 문제 일수 있습니다. 메니페스트 파일에 두번째 줄을 추가해보세요.

        <application
              android:requestLegacyExternalStorage="true"

  14. Favicon of https://toy9910.tistory.com BlogIcon 도리닥 2021.01.20 12:34 신고

    안드로이드 기본 카메라 어플을 사용하여 사진을 찍은 후에 해당 사진을 openCV로 roi에 영상처리를 할 수 있을까요?

  15. Favicon of https://phj9908.tistory.com BlogIcon pasongsong 2021.01.28 14:13 신고

    항상 감사합니다
    항상 잘 작동되었는데 이번에 노트북에서 작업을 하다가
    CMake Error at C:/Users/jeahee Park/AndroidStudioProjects/MyApplication0127/app/src/main/cpp/CMakeLists.txt:32 (set_target_properties):
    set_target_properties called with incorrect number of arguments. 이 오류가 계속 떠서요 ㅜㅜ
    set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${pathLIBOPENCV_JAVA}) 이 부분입니다.
    pathPROJECT랑 path OPENCV 이거 경로 다 맞게 했는데 이럽니다
    혹시 USER 이름중에 공백이 있어서 그런건 아니겠지요?

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.28 14:25 신고

      프로젝트가 꼬였을 가능성이 있어보입니다. 다시 프로젝트를 생성해보세요

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.28 16:01 신고

      1월 6일자로 기록해놓은 개발환경과 차이가 있나요?

  16. Favicon of https://opencv7example2.tistory.com BlogIcon 안스 2021.01.29 16:10 신고

    안녕하세요. 올려주신 자료로 설치하던 중에 계속 똑같은 오류가 떠서 질문드립니다..
    7. bit.ly/0613-07 코드를 붙이고 경로 설정을 하면 MainActivity.java 에 ConvertRGBtoGray 코드에 오류가 생깁니다. 찾아보니, 7 코드에서 경로 수정이 잘못되어서 그런것 같은데,
    제가 프로젝트를 생성할때 내 PC> 로컬디스크(C:) > OpenCV_Example 로 했는데 , 그럼
    set(pathPROJECT C:/opencv_example) # 수정필요
    set(pathOPENCV ${pathPROJECT}/sdk) # 수정필요
    이런 식으로 수정하면 안되는건가요...

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.01.29 16:49 신고

      pathPROJECT만 맞추면 동작해야 합니다. ConvertRGBtoGray에서 느낌표아이콘뜨는거 눌러서 C++ 함수는 생성했나요?

  17. Favicon of https://opencv7example2.tistory.com BlogIcon 안스 2021.01.29 21:07 신고

    답변주셔서 감사합니다!
    네!! 생성했어요! 동영상과 똑같이 느낌표 아이콘 눌러서 생성한 후에 -07 코드를 붙이면 ConvertRGBtoGray 에 CMakelist.txt 를 찾을수 없다는 오류가 생성됩니다..

  18. Favicon of https://opencv7example2.tistory.com BlogIcon 안스 2021.02.01 13:07 신고

    답장 감사드립니다!
    오류 메시지 입니다.
    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에 빨간밑줄이 뜹니다..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.02.01 14:24 신고

      혹시 한글이름이 경로나 프로젝트명에 있나요?

    • Favicon of https://opencv7example2.tistory.com BlogIcon 안스 2021.02.01 20:34 신고

      모두 영어로 되어있습니다..

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.02.01 20:41 신고

      안드로이드 스튜디어에서 처리중인데 진행중이라서 발생한것 일 수도 있어보입니다. 이 상태에서 해결방법을 찾기가 쉽지않아서 다시 진행해보는게 좋은듯합니다.

    • Favicon of https://opencv7example2.tistory.com BlogIcon 안스 2021.02.01 23:11 신고

      네!! 답변 너무 감사드립니다!

  19. Favicon of https://shjlee88.tistory.com BlogIcon StarvingDays 2021.04.01 23:47 신고

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

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.04.02 05:19 신고

      다음 포스트의 4번을 참고하세요

      https://webnautes.tistory.com/1087

  20. Favicon of https://skylain.tistory.com BlogIcon LSkyLain 2021.04.11 21:36 신고

    안녕하세요!
    웹나우테스 선생님 포스트들을 보며 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)

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

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

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

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

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

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

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

  21. Favicon of https://ddd66.tistory.com BlogIcon dfd666 2021.04.12 14:54 신고

    선생님 위에 예제 그대로 따라해서 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
    이렇게 오류가 뜹니다. 원인이 뭘까요 ? 답변해주시면 정말 감사하겠습니다

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.04.12 14:57 신고

      CMakeLists.txt에서 프로젝트 경로를 안바꾸신듯합니다. 에러 메시지에 제 컴퓨터 경로가 보이네요. c:/Users/webnautes....

    • Favicon of https://ddd66.tistory.com BlogIcon dfd666 2021.04.12 16:06 신고

      아 해결됐어요 감사합니다 !

    • Favicon of https://webnautes.tistory.com BlogIcon webnautes 2021.04.12 16:07 신고

      다행이네요. 축하드려요

+ Recent posts