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

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

引用 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 <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%')
  • 展示

总结

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

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

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

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/780344.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java-pytorch 使用手动下载FashionMNIST数据集进行测试

java-pytorch 使用手动下载FashionMNIST数据集进行测试 先定义训练数据和测试数据的位置查看一下读取到的标签数据格式使用loc和iloc访问下数据&#xff0c;便于下面操作使用read_image函数查看下图片的数据大小开始写数据集使用DataLoader去加载我们自己的数据看下加载后的dat…

FANUC机器人故障诊断—报警代码(一)

一、SRVO-050碰撞检测报警 [原因]检测出碰撞 [对策] 1.确认机器人是否碰撞。 2.确认是否正确进行了负载设定。 3.确认是否有过载、过度的加速度附加指令。 4.在长期停用后启动&#xff0c;或者外部气温较低时发生该报警。启动后&#xff0c;先短时间内低速运转设备&#…

vue3使用UEditorPlus 、后端配置、上传图片等处理

前端安装 vue3安装vue-ueditor-wrap // vue-ueditor-wrap v3 仅支持 Vue 3 npm i vue-ueditor-wrap3.x -S // or yarn add vue-ueditor-wrap3.x 下载 UEditorPlus 仓库地址 把dist文件复制到vue3项目中的public下&#xff0c;重命名为UEditorPlus UEditorPlus文档 在main.…

ArcGIS支持下SWAT与CENTURY模型的结合:流域水碳氮综合模拟

目录 专题一 流域水碳氮建模 专题二 数据准备 专题三 流域水模拟 专题四 流域氮模拟 专题五 流域碳模拟 专题六 模型结果分析及地图制作 更多应用 基于ArcGIS的SWAT模型是一类比较典型的流域模型&#xff0c;结合SWAT模型和生物地球化学循环模型可以实现流域水碳氮综合模…

根据实例逐行分析NIO到底在做什么

Selector&#xff08;选择器&#xff09;是 Channel 的多路复用器&#xff0c;它可以同时监控多个 Channel 的 IO 状况&#xff0c;允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。 选择器、通道、缓冲池是NIO的核心组件。 一、新建选择器 此时选择器内只包含…

Nginx-记

Nginx是一个高性能的web服务器和反向代理服务器&#xff0c;用于HTTP、HTTPS、SMTP、POP3和IMAP协议。因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。 &#xff08;1&#xff09;更快 这表现在两个方面&#xff1a;一方面&#xff0c;在正常情况下&…

【OpenGL】使用 python + Qt + OpenGL 的现代渲染

伴随资源 目录 一、说明二、 关于PyQt6.x2.1 QOpenGLWidget详细说明2.2 绘画技巧 三、PyOpenGL四、OpenGL 管线五、Python集成开发环境5.1 Emacs配置5.2 pycharm环境 六、你好&#xff0c;OpenGL&#xff01;七、QGL控件八、平截头体.svg九、定义几何9.1 立即模式与保留模式9…

OpenAI发布Voice Engine模型!用AI合成你的声音!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

比torchvision更强大,从timm库引用预训练模型和本地加载的方法

1&#xff0c;介绍 torchvision是大家最常用的预训练模型来源&#xff0c;但是其包含的预训练模型种类很少&#xff0c;往往并不能满足研究者们的需求。 而timm库提供了一个更强大的替代选项。 利用如下代码查询 import timmprint(len(timm.list_models())) 输出 1032 可…

Android Studio 2023.2.1版本 kotlin编译报错踩坑

1、需求 由于最近在整理项目&#xff0c;做一些公共基础组件Maven仓库封装&#xff0c;由于之前项目jar包和kotlin版本很老&#xff0c;kotlin版本1.3.72版本 Gradle使用5.4.1 Android Studio版本是2023.2.1&#xff0c;分别依次顺序如下图所示。 如下图所示 2、分析编译报错…

如何利用大模型LLM辅助,使用Python完成将CSV快速导入MySQL数据库

目录 一、适合场景 二、开发过程说明 三、功能使用流程 四、代码 1、安装python依赖库 2、完整代码段 一、适合场景 无废话&#xff0c;CSV中有少量不合规数据需要手工处理可利用此方法&#xff0c;适合有点经验的程序员&#xff0c;可以不熟Python&#xff0c;思路还是要…

【动手学深度学习-pytorch】-9.3深度循环神经网络

到目前为止&#xff0c;我们只讨论了具有一个单向隐藏层的循环神经网络。 其中&#xff0c;隐变量和观测值与具体的函数形式的交互方式是相当随意的。 只要交互类型建模具有足够的灵活性&#xff0c;这就不是一个大问题。 然而&#xff0c;对一个单层来说&#xff0c;这可能具有…

Oracle 19C RAC集群补丁升级

文章目录 一、补丁包概述二、OPatch检查和更新Grid用户更新OPatchOracle用户更新OPatch 三、验证Oracle Inventory的有效性四、运行 OPatch 冲突检查五、运行opatch命令检查GI HOME下是否有足够的空间六、补丁冲突检测与解决&#xff08;修补程序&#xff09;七、使用root用户应…

Linux - 第三节

改变用户类型 su 仅单纯的进行身份变化 依旧处于普通用户里面 su - 进行重新登录更改身份 退出用exit / ctrld su 用户名 改成成其他身份 对一条命令进行提权 sudo command r:可读 w:可写 x:可执行 -:对应的权限位置&#xff0c;没有权限 去掉所有权限 chmod u…

多视图三维重建-SFM简介

背景 掌握传统的多视图三维重建基本流程 总体流程 多视图三维重建的Pipieline如下图&#xff0c;总共分为四个步骤&#xff1a; 拍摄场景多视角的图像建立这些图像之间的联系&#xff08;Data Association&#xff09;SFM稀疏重建MVS稠密重建 Data Association 建立图像…

向开发板上移植ip工具:将ip工具移植到开发板系统中

一. 简介 前面一篇文章对 ip工具源码进行了交叉编译&#xff0c;生成了ip工具。文章如下&#xff1a; 向开发板上移植ip工具&#xff1a;交叉编译 ip工具-CSDN博客 本文对生成的 ip工具进行移植&#xff0c;即移植到开发板系统中&#xff0c;并确定是否可用。 二. 向开发板…

Nagios工具

一 nagios 相关概念 Nagios 是一款开源的免费网络监视工具&#xff0c;能有效监控 Windows、Linux 和 Unix 的主机状态&#xff0c;交换机路由器等网络设置&#xff0c;打印机等。在系统或服务状态异常时发出邮件或短信报警第 一时间通知网站运维人员&#xff0c;在状态恢复后…

顶顶通呼叫中心中间件-声音编码自适应配置方法(mod_cti基于FreeSWITCH)

顶顶通呼叫中心中间件-声音编码自适应配置方法讲解(mod_cti基于FreeSWITCH) 声音编码自适应介绍 声音编码自适应&#xff0c;通常在语音通信和音频处理领域中指的是一种能够根据信号特性和传输环境自动调整编码参数的技术。其目的是在不同的网络状况和音质要求下&#xff0c;…

5-规范设计(下):commit信息风格迥异、难以阅读,如何规范?

我们在做代码开发时&#xff0c;经常需要提交代码&#xff0c;提交代码时需要填写 Commit Message&#xff08;提交说明&#xff09;&#xff0c;否则就不允许提交。 所以在 Go 项目开发时&#xff0c;一个好的 Commit Message 至关重要&#xff1a; 可以使自己或者其他开发人…