|
背景
OpenCV介绍
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库。它由一系列的C函数和少量C++类构成,同时提供Python、Java和MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV具有极广的应用领域,它包括但不限于:
人脸识别和物体识别:这是OpenCV的一项重要功能,应用在许多领域,如安全监控、交互设计等。图像和视频分析:如图像增强、图像分割、视频跟踪等。图像合成和3D重建:在图像处理和计算机视觉领域,OpenCV可以用于创建AR或VR效果,生成3D模型等。机器学习:OpenCV内置了大量的机器学习算法,可以用于图像分类、聚类等任务。深度学习:OpenCV中的dnn模块提供了一系列深度学习模型的接口,用户可以加载预训练模型进行图像识别、目标检测等任务。
本文主要介绍OpenHarmony如何用opencvlib进行应用样例开发
应用开发
创建HAP
通过DevEcoStudio创建项目“File->New->Create Project"创建一个工程
引用OpenCV lib库
引入opencv头文件库,放在include目录下
引入lib库,放在libs目录下
修改CMAKE
- 增加common头文件和cpp文件
- //
- // Created on 2024/3/5.
- //
- // Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
- // please include "napi/native_api.h".
- #ifndef OpencvSample_common_H
- #define OpencvSample_common_H
- #include
- #include
- #include
- #include
- #include
- #include "opencv2/opencv.hpp"
- #include "opencv2/imgcodecs/legacy/constants_c.h"
- #include "hilog/log.h"
- #include "napi/native_api.h"
- #include "rawfile/raw_file_manager.h"
- #include "rawfile/raw_file.h"
- #include "rawfile/raw_dir.h"
- #define GLOBAL_RESMGR (0xFFEE)
- constexpr int32_t RGB_565 = 2;
- constexpr int32_t RGBA_8888 = 3;
- constexpr int32_t STR_MAX_SIZE = 200;
- constexpr int32_t LONG_STR_MAX_SIZE = 1024;
- constexpr int32_t ERR_OK = 0;
- constexpr int8_t NO_ERROR = 0;
- constexpr int8_t ERROR = -1;
- constexpr uint8_t PARAM0 = 0;
- constexpr uint8_t PARAM1 = 1;
- constexpr uint8_t PARAM2 = 2;
- constexpr uint8_t PARAM3 = 3;
- constexpr uint8_t PARAM4 = 4;
- constexpr uint8_t PARAM5 = 5;
- constexpr uint8_t PARAM6 = 6;
- constexpr uint8_t PARAM7 = 7;
- constexpr uint8_t PARAM8 = 8;
- constexpr uint8_t PARAM9 = 9;
- constexpr uint8_t PARAM10 = 10;
- constexpr uint8_t PARAM11 = 11;
- constexpr uint8_t PARAM12 = 12;
- constexpr int32_t ARGS_ONE = 1;
- constexpr int32_t ARGS_TWO = 2;
- constexpr int32_t ONLY_CALLBACK_MAX_PARA = 1;
- constexpr int32_t ONLY_CALLBACK_MIN_PARA = 0;
- struct CallbackPromiseInfo {
- napi_ref callback = nullptr;
- napi_deferred deferred = nullptr;
- bool isCallback = false;
- int32_t errorCode = 0;
- };
- template void FreeMemory(T *p) {
- if (p == nullptr) {
- return;
- }
- delete p;
- p = nullptr;
- }
- template void FreeMemoryArray(T *p) {
- if (p == nullptr) {
- return;
- }
- delete[] p;
- p = nullptr;
- }
- #define NAPI_RETVAL_NOTHING
- #define NAPI_CALL_BASE(env, theCall, retVal) \
- do { \
- if ((theCall) != 0) { \
- return retVal; \
- } \
- } while (0)
- #define NAPI_CALL(env, theCall) NAPI_CALL_BASE(env, theCall, nullptr)
- #define NAPI_CALL_RETURN_VOID(env, theCall) NAPI_CALL_BASE(env, theCall, NAPI_RETVAL_NOTHING)
- extern bool GetMatFromRawFile(napi_env env, napi_value jsResMgr, const std::string &rawfileDir,
- const std::string &fileName, cv::Mat &srcImage);
- extern bool cvtMat2Pixel(cv::InputArray _src, cv::OutputArray &_dst, int code);
- extern napi_value NapiGetNull(napi_env env);
- extern uint32_t GetMatDataBuffSize(const cv::Mat &mat);
- extern bool CreateArrayBuffer(napi_env env, uint8_t *src, size_t srcLen, napi_value *res);
- extern napi_value NapiGetUndefined(napi_env env);
- extern napi_value GetCallbackErrorValue(napi_env env, int32_t errCode);
- extern napi_value NapiGetBoolean(napi_env env, const bool &isValue);
- extern uint32_t GetMatDataBuffSize(const cv::Mat &mat);
- extern void SetCallback(const napi_env &env, const napi_ref &callbackIn, const int32_t &errorCode,
- const napi_value &result);
- extern void SetPromise(const napi_env &env, const napi_deferred &deferred, const int32_t &errorCode,
- const napi_value &result);
- extern void ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result);
- extern napi_value JSParaError(const napi_env &env, const napi_ref &callback);
- extern void PaddingCallbackPromiseInfo(const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info,
- napi_value &promise);
- extern bool WrapJsPixelInfoInfo(napi_env env, cv::Mat &outMat, napi_value &result);
- #endif //OpencvSample_common_H
复制代码 - 增加灰度转换方法
- using namespace std;
- using namespace cv;
- static const char *TAG = "[opencv_img2Gray]";
- napi_value Img2Gray(napi_env env, napi_callback_info info) {
- OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "Img2Gray Begin");
- napi_value result = NapiGetNull(env);
- size_t argc = 3;
- napi_value argv[3] = {nullptr};
- napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
- size_t strSize;
- char strBuf[256];
- napi_get_value_string_utf8(env, argv[1], strBuf, sizeof(strBuf), &strSize);
- std::string fileDir(strBuf, strSize);
- OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "fileDir:%{public}s", fileDir.c_str());
- napi_get_value_string_utf8(env, argv[2], strBuf, sizeof(strBuf), &strSize);
- std::string fileName(strBuf, strSize);
- OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "fileName:%{public}s", fileName.c_str());
- Mat srcImage;
- if (!GetMatFromRawFile(env, argv[0], fileDir, fileName, srcImage)) {
- OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "Get Mat from rawfile failed!.");
- return result;
- }
- Mat srcGray;
- cvtColor(srcImage, srcGray, COLOR_RGB2GRAY);
- // 將图像转换为pixelMap格式
- Mat outMat;
- cvtMat2Pixel(srcGray, outMat, RGBA_8888);
- OH_LOG_Print(LOG_APP, LOG_INFO, GLOBAL_RESMGR, TAG, "outMat size: %{public}d, cols:%{public}d, rows:%{public}d",
- outMat.total(), outMat.cols, outMat.rows);
- napi_create_object(env, &result);
- bool retVal = WrapJsPixelInfoInfo(env, outMat, result);
- if (!retVal) {
- OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, TAG, "WrapJsInfo failed!.");
- }
- return result;
- }
复制代码 - 导出 //hello.cpp
- EXTERN_C_START
- static napi_value Init(napi_env env, napi_value exports)
- {
- napi_property_descriptor desc[] = {
- {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
- {"img2Gray", nullptr, Img2Gray, nullptr, nullptr, nullptr, napi_default, nullptr}
- };
- napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
- return exports;
- }
- EXTERN_C_END
复制代码 - 导出接口 //index.d.ts
- import resourceManager from '@ohos.resourceManager';
- export interface PixelInfo {
- rows: number;
- cols: number;
- buffSize: number;
- byteBuffer: ArrayBuffer;
- }
- export const add: (a: number, b: number) => number;
- export const img2Gray: (resmgr: resourceManager.ResourceManager, path: string, file: string) => PixelInfo;
复制代码 - 在页面添加交互 // index.ets
- Column() {
- Image(this.isGray ? this.imagePixelMap : $rawfile('lena.jpg'))
- .margin({ left: 24, right: 24 })
- .objectFit(ImageFit.Contain)
- .id('backBtn')
- }
- .width('100%')
- .height('60%')
- .alignItems(HorizontalAlign.Center)
- .justifyContent(FlexAlign.Start)
- Row() {
- Button($r('app.string.image_gray'), { type: ButtonType.Capsule })
- .backgroundColor(this.isGray ? Color.Gray : Color.Blue)
- .margin({ left: 24 })
- .width('30%')
- .id('imageGray')
- .enabled(this.isGray ? false : true)
- .onClick(() => {
- let pixelInfo: testNapi.PixelInfo = testNapi.img2Gray(getContext().resourceManager, '', 'lena.jpg');
- Logger.info(TAG, `pixelInfo buffSize: ${pixelInfo.buffSize}`);
- let opts: image.InitializationOptions = {
- editable: true,
- pixelFormat: this.pixelMapFormat,
- size: { height: pixelInfo.rows, width: pixelInfo.cols }
- }
- image.createPixelMap(pixelInfo.byteBuffer, opts, (error, pixelmap) => {
- if (error) {
- Logger.error(TAG, `Failed to create pixelmap error_code ${error.code}`);
- } else {
- Logger.info(TAG, 'Succeeded in creating pixelmap.');
- this.imagePixelMap = pixelmap;
- }
- })
- this.isGray = true;
- })
- Button($r('app.string.image_recover'), { type: ButtonType.Capsule })
- .backgroundColor(Color.Blue)
- .width('30%')
- .id('imageRecover')
- .onClick(() => {
- this.isGray = false;
- })
- }
- .width('100%')
复制代码 展示
总结
可以用nativec++方式导入opencv库直接开发应用,目前实现了一个简单接口,后面会实现场景应用
目前只能做到可用,还有以下问题:
需要NAPI接口进行ArkTS和C/C++交互速度比较慢,是否可以通过GPU加速Arkts和native交互多,考虑转用xcomponent方式
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|