如何在Flutter的本机C ++中使用OpenCV 4?
我需要编写一些使用OpenCV的 C 代码,Flutter代码将调用这些C 代码。
有关于使用Flutter编写C ++的教程,但是我找不到有关使用OpenCV的任何最新且易于部署的解决方案。怎么做?
回答:
这是我的解决方案。
特征
- 适用于Android和iOS。
- 使用静态链接而不是动态链接。(因此,代码大小要小得多。)
- 最新版本为2020.07.28。(由于这些API的变化很快,而且许多文章都有些陈旧。)
入门
注意:如果您已经有一个应用程序,则可以跳过本节:)本节假定您根本没有任何代码。
可以从此处下载示例代码。
:确保您具有Flutter环境,并遵循官方的“使用Flutter编写C
++”教程。
注意 : 必须 遵循“在iOS上,您需要告诉Xcode静态链接文件:…”的步骤。否则,在我们的最后一步,iOS将抱怨找不到该符号。
:使用OpenCV编写所需的任何代码。例如,我更改ios/Classes/native_add.cpp
为以下愚蠢的代码,与官方教程中的代码几乎相同:
#include <stdint.h>#include <opencv2/core.hpp>
extern "C" __attribute__((visibility("default"))) __attribute__((used))
int32_t native_add(int32_t x, int32_t y) {
cv::Mat m = cv::Mat::zeros(x, y, CV_8UC3);
return m.rows + m.cols;
}
安卓系统
:从官方网站下载Android OpenCV sdk
。假设我将其放在桌面上。/Users/tom/Others/OpenCVRelease/OpenCV-
android-sdk
:将更android/CMakeLists.txt
改为以下内容。 注意
:首先将更OPENCV_BASE_DIR
改为您的文件夹。
cmake_minimum_required(VERSION 3.4.1)# TODO please change me!
set(OPENCV_BASE_DIR "TODO PLEASE PUT YOUR DIR HERE!!!")
set(OPENCV_INCLUDE_DIR "${OPENCV_BASE_DIR}/sdk/native/jni/include/")
set(OPENCV_STATIC_LIB_DIR "${OPENCV_BASE_DIR}/sdk/native/staticlibs/${ANDROID_ABI}")
set(OPENCV_3RDPARTY_STATIC_LIB_DIR "${OPENCV_BASE_DIR}/sdk/native/3rdparty/libs/${ANDROID_ABI}")
include_directories(${OPENCV_INCLUDE_DIR})
find_library(log-lib log)
add_library(highgui STATIC IMPORTED)
set_target_properties(highgui PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_highgui.a)
add_library(calib3d STATIC IMPORTED)
set_target_properties(calib3d PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_calib3d.a)
add_library(core STATIC IMPORTED)
set_target_properties(core PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_core.a)
add_library(dnn STATIC IMPORTED)
set_target_properties(dnn PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_dnn.a)
add_library(flann STATIC IMPORTED)
set_target_properties(flann PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_flann.a)
add_library(imgproc STATIC IMPORTED)
set_target_properties(imgproc PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_imgproc.a)
add_library(videoio STATIC IMPORTED)
set_target_properties(videoio PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_videoio.a)
add_library(imgcodecs STATIC IMPORTED)
set_target_properties(imgcodecs PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_imgcodecs.a)
add_library(features2d STATIC IMPORTED)
set_target_properties(features2d PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_features2d.a)
add_library(ml STATIC IMPORTED)
set_target_properties(ml PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_ml.a)
add_library(photo STATIC IMPORTED)
set_target_properties(photo PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_photo.a)
add_library(shape STATIC IMPORTED)
set_target_properties(shape PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_shape.a)
add_library(objdetect STATIC IMPORTED)
set_target_properties(objdetect PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_objdetect.a)
add_library(stitching STATIC IMPORTED)
set_target_properties(stitching PROPERTIES IMPORTED_LOCATION ${OPENCV_STATIC_LIB_DIR}/libopencv_stitching.a)
include(AndroidNdkModules)
android_ndk_import_module_cpufeatures()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
add_library(tbb STATIC IMPORTED)
set_target_properties(tbb PROPERTIES IMPORTED_LOCATION ${OPENCV_3RDPARTY_STATIC_LIB_DIR}/libtbb.a)
add_library(tegra_hal STATIC IMPORTED)
set_target_properties(tegra_hal PROPERTIES IMPORTED_LOCATION ${OPENCV_3RDPARTY_STATIC_LIB_DIR}/libtegra_hal.a)
add_library(ittnotify STATIC IMPORTED)
set_target_properties(ittnotify PROPERTIES IMPORTED_LOCATION ${OPENCV_3RDPARTY_STATIC_LIB_DIR}/libittnotify.a)
add_library(native_with_opencv
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
../ios/Classes/native_add.cpp
)
target_link_libraries(native_with_opencv
${log-lib}
core
# note: You can import whatever other modules you like (e.g. dnn)
tbb # note: need to be placed *after* "core"
cpufeatures
ittnotify
tegra_hal # NOTE if still have error, check abiFilters, since tegra does *not* exist in x86.
Threads::Threads
-lz
)
当然,lib/native_with_opencv.dart
应该将.so
文件名更改为"libnative_with_opencv.so"
。
:更改android/build.gradle
以下内容:
android { ...
defaultConfig {
...
// [[[CHANGE 1: Make minSdkVersion bigger]]]
// see https://github.com/opencv/opencv/issues/14419
minSdkVersion 21
// [[[CHANGE 2: Add these flags and filters]]]
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions -std=c++11"
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
...
}
...
}
当然,minSdkVersion
实际项目(native_with_opencv/example/android/app/build.gradle
)中的也应更改为21。
编译并享受它(并转到iOS的下一部分)!如果看到1 + 2 == 3
,则一切正常。
奖励:如果您在发布模式下构建并查看apk大小,您将看到我们的.so
文件小于1MB。因此,静态链接和减小文件大小确实有效:)
的iOS
:在中ios/native_with_opencv.podspec
,添加:
s.static_framework = true s.dependency 'OpenCV', '~> 4.1'
:编译并享受。 注意: 您可能需要先运行pod
install下native_with_opencv/example/ios
让Cocoapod初始化。
(可选)Android配置如何工作的说明:(1)最初,我只是链接core
,但是有数百个链接错误。然后,我搜索并修复每个组。例如,error:
undefined reference to
'carotene_o4t::...'意味着我需要与链接libtegra_hal
,因此我添加了几行。(2)奇怪的是,tbb
应该放在 之后
core
,否则它仍然不会链接。(3)abiFilters
是必需的,因为tegra_hal
不支持x86
(因此不.a
存在文件)。(4)minSdkVersion
需要复活,否则fegetenv
将找不到。
以上是 如何在Flutter的本机C ++中使用OpenCV 4? 的全部内容, 来源链接: utcz.com/qa/405323.html