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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
1.openCV 안드로이드용 빌드 설치후 newProject에서 맨 아래에 Native C++ 클릭
 
2.안드로이드 스튜디오에서 file -> new -> import module -> openCV SDK 폴더 지정 -> 이름을 :opencv로 수정
 
3.file -> project structure -> 왼쪽탭 Dependencies 클릭 -> module 목록에서 app클릭후 +기호 클릭. -> module Dependency 클릭 -> opencv 체크후 저장.
 
4.styles.xml에 다음을 추가 ( resources 안에 다른 item 밑에 추가. ) 전체화면으로 보기위한 용도.
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
 
 
5. 레이아웃 복사
 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:opencv="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
 
    android:orientation="vertical"
    tools:context=".MainActivity">
 
    <org.opencv.android.JavaCameraView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        opencv:camera_id="any"
        android:visibility="gone"
        android:id="@+id/activity_surface_view" />
 
</LinearLayout>
 
6. 메니페스트 추가 application태그 위에 붙여넣기
 
<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" />
 
 
7. 메니페스트에 카메라 방향 넣기. 원래 <activity 태그가 시작하는 줄을 지우고 복사
<activity android:name=".MainActivity"
    android:screenOrientation="landscape"
    android:configChanges="keyboardHidden|orientation">
 
 
8. 메인엑티비티 복사 , 임포트 밑에다가 다 지우고 붙여넣기
 
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();
    }
 
 
}
 
 
9. ConvertRGBtoGray 함수가 빨간데 클릭해서 왼쪽에 전구누르고 create function 클릭
 
10. 방금만든 함수의 extern "C" 윗줄 부터 include 전까지 삭제 
 
11.cpp 파일에 다음을 추가
 
<윗줄에 >
#include <opencv2/opencv.hpp>
 
using namespace cv;
 
 
 
< 방금만든 함수에 > 
Mat &matInput = *(Mat *)matAddrInput;
Mat &matResult = *(Mat *)matAddrResult;
 
cvtColor(matInput, matResult, COLOR_RGBA2GRAY);
 
 
12.cpp 폴더 cmakelist 파일을 전부다 지우고 밑에줄 복사
# 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}/opencv)
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} )
 
 
13. 해당 파일에 pathPROJECT 경로를 내 프로젝트 경로와 이름으로 변경
안드로이드 스튜디오 왼쪽 상단에 있다.
 
14. file -> sync Project with Gradle Files 클릭
 
15. cpp 파일에 붉은줄이 사라졌는지 확인
 
 
 
 
 
 
 
 
 
 
 
 
cs


+ Recent posts