OpenHarmony OpenCV应用样例开发

这篇具有很好参考价值的文章主要介绍了OpenHarmony OpenCV应用样例开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

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"创建一个工程

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

  • 工程创建完毕后,界面入口为 Index.ets

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

引用 OpenCV lib 库
  • 引入 opencv 头文件库,放在 include 目录下

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

  • 引入 lib 库,放在 libs 目录下

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

  • 修改 CMAKE

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

  • 增加 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 <string>
    #include <stdio.h>
    #include <js_native_api.h>
    #include <js_native_api_types.h>
    #include <vector>
    #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 <typename T> void FreeMemory(T *p) {
        if (p == nullptr) {
            return;
        }
        delete p;
        p = nullptr;
    }

    template <typename T> 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%')

  • 展示

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

总结

  • 可以用 nativec++ 方式导入 opencv 库直接开发应用,目前实现了一个简单接口,后面会实现场景应用

  • 目前只能做到可用,还有以下问题:

    • 需要 NAPI 接口进行 ArkTS 和 C/C++ 交互
    • 速度比较慢,是否可以通过 GPU 加速
    • Arkts 和 native 交互多,考虑转用 xcomponent 方式

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. ……

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

OpenHarmony OpenCV应用样例开发,移动开发,HarmonyOS,OpenHarmony,opencv,人工智能,计算机视觉,harmonyos,鸿蒙开发,Openharmony,移动开发文章来源地址https://www.toymoban.com/news/detail-851462.html

到了这里,关于OpenHarmony OpenCV应用样例开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HarmonyOS/OpenHarmony应用开发-HDC环境变量设置

    hdc(HarmonyOS Device Connector)是 HarmonyOS 为开发人员提供的用于调试的命令行工具,通过该工具可以在 windows/linux/mac 系统上与真实设备或者模拟器进行交互。 hdc 工具通过 HarmonyOS SDK 获取,存放于 /Huawei/Sdk/openharmony/版本号/toolchains/ 目录下。 1、打开环境变量 2、新建系统变量 3、

    2024年04月15日
    浏览(56)
  • HarmonyOS/OpenHarmony(Stage模型)应用开发单一手势(二)

    三、拖动手势(PanGesture) .PanGestureOptions(value?:{ fingers?:number; direction?:PanDirection; distance?:number}) 拖动手势用于触发拖动手势事件,滑动达到最小滑动距离(默认值为5vp)时拖动手势识别成功,拥有三个可选参数: fingers:非必选参数,用于声明触发拖动手势所需要的最少手指数

    2024年02月09日
    浏览(57)
  • HarmonyOS/OpenHarmony(Stage模型)应用开发单一手势(三)

    RotationGesture (value?:{ fingers ? :number ; angle ? :number }) 旋转手势用于触发旋转手势事件,触发旋转手势的最少手指数量为2指,最大为5指,最小改变度数为1度,拥有两个可选参数: fingers:非必选参数,用于声明触发旋转手势所需要的最少手指数量,最小值为2,最大值为5,默认值

    2024年02月09日
    浏览(54)
  • HarmonyOS/OpenHarmony应用开发-ArkTS语言基本语法说明

    图1  示例效果图   本示例中,ArkTS的基本组成如下所示。 图2  ArkTS的基本组成     装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如上述示例中@Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组

    2024年02月07日
    浏览(55)
  • HarmonyOS/OpenHarmony应用开发-ArkTSAPI系统能力SystemCapability列表

    SysCap,全称SystemCapability,即系统能力,指操作系统中每一个相对独立的特性。 开发者使用某个接口进行开发前,建议先阅读 系统能力使用说明 ,了解Syscap的定义和使用指导。 说明 当前列表枚举出3.1 Beta版本中支持的系统能力。开发者可以在SDK中通过phone.json文件查询。 Sy

    2024年02月13日
    浏览(39)
  • HarmonyOS/OpenHarmony应用开发-程序包多HAP机制(上)

    一、多HAP机制设计目标 方便开发者模块化的管理应用,好的应用一般都是模块化管理,模块之间属于松耦合关系。多HAP方便了开发者将业务划分成多个模块,每个模块放到独立的HAP中。例如支付类应用,有统一的主界面,主界面管理“扫一扫”、“收付款”、“消息”、“理

    2024年02月15日
    浏览(50)
  • HarmonyOS/OpenHarmony应用开发-程序包多HAP机制(下)

    三、多HAP的开发调试与发布部署流程 (一)多HAP的开发调试与发布部署流程如下图所示。 图1 多HAP的开发调试与发布部署流程   (二)开发 开发者通过DevEco Studio工具按照业务的需要创建多个Module,在相应的Module中完成自身业务的开发。 (三)调试 通过DevEco Studio编译打包

    2024年02月17日
    浏览(51)
  • HarmonyOS/OpenHarmony应用开发-Stage模型UIAbility组件使用(一)

    一、UIAbility组件概述 1.概述 UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。 UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口;一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近任务列表中的

    2024年02月11日
    浏览(54)
  • HarmonyOS/OpenHarmony应用开发-Stage模型UIAbility组件使用(六)

    本文将从如下场景分别介绍设备内UIAbility间的交互方式。 启动应用内的UIAbility。启动应用内的UIAbility并获取返回结果。启动其他应用的UIAbility。启动其他应用的UIAbility并获取返回结果。启动UIAbility的指定页面。通过Call调用实现UIAbility交互(仅对系统应用开放)。 当使用隐式

    2024年02月16日
    浏览(54)
  • HarmonyOS/OpenHarmony应用开发-Stage模型UIAbility组件使用(五)

    UIAbility组件间交互(设备内) UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时,会涉及到启动特定的UIAbility,该UIAbility可以是应用内的其他UIAbility,也可以是其他应用的UIAbility(例如启动三方支付UIAbility)。 本文将从如下场景分别介绍设备内UIAbility间的交互

    2024年02月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包