Opencv On Android Studio: 使用获取手机摄像头数据并显示
-
- 新建空项目
- 将opencv的Java库作为Module导入
具体步骤为: File->new->Import,选择opencv-4.1.1-android-sdk\OpenCV-android-sdk\sdk(opencv-4.1.1-android-sdk从Opencv官网下载)
-
- 修改opencv的build.gradle文件版本号
具体做法是,将文件列表上方的显示模式由Android切换至 Project,并展开文件列表。分别打开app\build.gradle文件和opencv411\build.gradle文件,将opencv411\build.gradle的几个版本号改成app\build.gradle文件里相同即可,然后在在文本域上点击 Try Again或工具栏图标。
-
- 添加opencv411作为项目依赖module
打开File->Project Structure,在Modules里选择app,右侧进入Dependencies,点击加号,选择Module dependency。
-
- AndroidMainfest.xml文件中添加Opencv权限
AndroidMainfest.xml的路径为myopencvTest\app\src\main\AndroidMainfest.xml
<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"/>
-
- 修改activity_main.xml的内容
activity_main.xml 的路径为myopencvTest\app\src\main\res\layout\activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:opencv="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <org.opencv.android.JavaCameraView android:layout_width="fill_parent" android:layout_height="fill_parent" android:visibility="gone" android:id="@+id/tutorial1_activity_java_surface_view" opencv:show_fps="true" opencv:camera_id="any" /> </FrameLayout>
-
- 修改MainActivity.java的内容
内容如下所示:
public class MainActivity extends CameraActivity implements CameraBridgeViewBase.CvCameraViewListener2 { private static final String TAG = "OCVSample::Activity"; private CameraBridgeViewBase mOpenCvCameraView; private boolean mIsJavaCamera = true; private MenuItem mItemSwitchCamera = null; private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { Log.i(TAG, "OpenCV loaded successfully"); mOpenCvCameraView.enableView(); } break; default: { super.onManagerConnected(status); } break; } } }; public MainActivity() { Log.i(TAG, "Instantiated new " + this.getClass()); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "called onCreate"); super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.activity_main); mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); } @Override public void onPause() { super.onPause(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } @Override public void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization"); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback); } else { Log.d(TAG, "OpenCV library found inside package. Using it!"); mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS); } } @Override protected List<? extends CameraBridgeViewBase> getCameraViewList() { return Collections.singletonList(mOpenCvCameraView); } public void onDestroy() { super.onDestroy(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } public void onCameraViewStarted(int width, int height) { } public void onCameraViewStopped() { } public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { return inputFrame.rgba(); } }
-
- 参考网址
https://www.jianshu.com/p/6e16c0429044
Android Studio 使用CMake并用jni调用opencv函数
-
- 将CMakelists.txt复制到工程app目录之下,如下图所示
-
- 在CMakelists.txt中添加使用opencv的so库及cpp文件,并包含头文件
修改后的CMakelists.txt如下所示:
cmake_minimum_required(VERSION 3.4.1) # OpenCV stuff set(OpenCV_DIR D:/ProgramData/opencv/OpenCV-android-sdk/sdk/native/jni) find_package(OpenCV REQUIRED) 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). # Associated headers in the same location as their source # file are automatically included. src/main/cpp/native-lib.cpp ) 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 ) include_directories(D:/ProgramData/opencv/OpenCV-android-sdk/sdk/native/jni/include) add_library( lib_opencv SHARED IMPORTED ) set_target_properties( lib_opencv PROPERTIES IMPORTED_LOCATION D:/ProgramData/opencv/OpenCV-android-sdk/sdk/native/libs/armeabi-v7a/libopencv_java4.so ) target_link_libraries( # Specifies the target library. native-lib # OpenCV lib ${lib_opencv} # Links the target library to the log library # included in the NDK. ${log-lib} )
-
- 修改gradle配置,将gradle与CMakelists.txt的原生库关联,并指定ABI
其中,添加的模块为:
ndk{
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
}
}
配置gradle与CMakelist文件关联,内容如下所示:
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
修改后的app/build.gradle内容如下所示:
apply plugin: 'com.android.application' android { compileSdkVersion 29 buildToolsVersion "29.0.1" defaultConfig { applicationId "com.example.testapplication" minSdkVersion 26 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" ndk{ abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' } externalNativeBuild { cmake { cppFlags "-frtti -fexceptions" abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' } } } externalNativeBuild { cmake { path "CMakeLists.txt" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'com.google.android.material:material:1.0.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' compile project(path: ':opencv411sdk') }
-
- MainActivity.java中添加自定义的C++库
System.loadLibrary("native-lib");
-
- 调用jni函数
定义:
public native void salt(long matAddrGray, int nbrElem);
调用:
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { Mat matGray = inputFrame.gray(); salt(matGray.getNativeObjAddr(), 100); Log.i(TAG, "onCameraFrame"); return matGray; }
-
- 参考网址
https://www.jianshu.com/p/23af9151837e