ML Kit:通过Mendix 集成人脸识别算法

预训练模型是一种已经使用训练数据集进行训练并包含执行模型所需所有参数的机器学习模型。这类模型常用于计算机视觉领域,比如可以在Mendix Studio Pro中导入ONNX模型后,可以在微流程中执行该模型。

image.png

本文讲述如何在Mendix应用程序中集成特定的人脸检测模型。其中一个重要步骤是添加所需的预处理和后处理步骤,并以Java代码形式实现。这里提供了详细的Java代码示例:Mendix ML Kit Demo

Face Detection model

我们想要使用的ML模型是ONNX模型库中的一个轻量级人脸检测模型。这里有两个模型可供选择,它们在输入分辨率上有所不同。我们选择了RFB-640模型,它需要一个分辨率为640x480像素的RGB图像。该模型的输出是两个列表,包含了边界框和相应的得分。一个边界框由其左侧、顶部、右侧和底部的边界位置定义。

在Mendix中映射模型

在Mendix文档中已经很好地描述了导入和调用ONNX ML模型的几个简单步骤。面部识别模型为调用模型生成了以下输入和输出映射。

image.png

为了在Mendix中调用模型,我们创建一个输入实体的实例,并将其传递给Call ML model 的微流组件。

image.png

如我们所见,这里的输入和输出数据需要一种特殊格式。为了转换这些数据,需要进行一些预处理和后处理。

预处理和后处理

对于这个特定问题,Mendix中没有标准的处理方法。因此,这里的处理是通过两个Java动作完成的,这些动作完成了大部分工作。

image.png

映射输入数据

图像必须以包含形状为[1,3,480,640]的张量的二进制数据传递。您可以在这里了解更多关于张量和形状的信息:TensorFlow Core中的张量简介

要运行模型,需要进行以下步骤:

  • 将输入图像缩放到640x480像素的RGB格式。
  • 将图像转换为具有匹配形状和标准化值的矩阵。
  • 将矩阵编码成可以传递给ML模型的格式。

图像读取和缩放

为了缩放图像,我们将使用OpenCV库及其Java封装。由于OpenCV需要本地库,我们将遵循与Mendix ML学习套件相同的方法,使用打包有本地库的库。

在我们可以使用任何OpenCV功能之前,我们需要加载共享库。这可以在静态代码段中完成。

// BEGIN EXTRA CODE
static {nu.pattern.OpenCV.loadShared(); //OpenCV initialization
}

我们可以读取输入图像并使用OpenCV的resize方法进行转换。

// read the image into a matrix
InputStream istream = com.mendix.core.Core.getFileDocumentContent(getContext(), sourceImage.getMendixObject());
MatOfByte matOfByte = new MatOfByte(istream.readAllBytes());
Mat sourceImage = Imgcodecs.imdecode(matOfByte, Imgcodecs.IMREAD_COLOR);// resize the image to the target size
Mat rim = new Mat();
Imgproc.resize(sourceImage, rim, new Size(640,480));

将图像转换为矩阵

下一步是将图像转换为矩阵并标准化值。人脸检测模型期望输入数据缩放到[-1;1]的范围。这种转换可以使用以下代码完成。

float[][][][] inputArray = new float[1][3][480][640];
for(int i = 0; i < 480; i++) {for(int j = 0; j < 640; j++) {for(int k = 0; k <= 2; k++) {double[] rawValue = rim.get(i, j);float normalizedValue = ((float) (rawValue[Math.abs(k - 2)] - 127) / 128);inputArray[0][k][i][j] = normalizedValue;}}
}

为处理编码矩阵

现在必须将结果的inputArray矩阵传递给模型。Mendix ML Kit已经提供了一些辅助函数,用于对这些数据进行base64编码。这个Java动作的结果被写入模型的输入对象。

InputStream is = MLKit.toInputStream(inputArray);
String base64data = MLKit.toBase64(is);

映射输出数据(后处理)

模型生成了两个多维矩阵(得分和边界框),它们以base64编码的二进制形式。为了处理这些输出,我们使用一个后处理Java动作。对于解码原始数据,我们可以再次使用MLKit的辅助函数。

float[][][] _box = new float[1][17640][4];
InputStream isb = MLKit.fromBase64(rfb640Output.getBoxes());
MLKit.toArray(isb, _box);

对于解码计算出的得分,使用相同的代码。输出数据的形状是[1,17640,4]。这意味着模型总是生成17640个潜在面孔的候选者。为了识别最终的检测到的面孔列表,需要进行一些额外的过滤,这不是模型本身完成的。

过滤模型输出

后处理包括两个步骤。第一步是根据它们的得分过滤结果,并将候选者限制在较小的集合中。sortedCandidateIdx的结果是指向候选者的一组索引。

List<Integer> sortedCandidateIdx = IntStream.range(0, 17640)
.filter(idx -> score[idx][1] > detectionThreshold)
.boxed().sorted(new Comparator<Integer>() {@Overridepublic int compare(Integer idx1, Integer idx2) {return Float.compare(score[idx2][1] ,score[idx1][1]);}
}).limit(candidates).collect(Collectors.toList());

得分是指定框中含有面孔的可能性的指示器。这些候选者现在是输入图像中检测到的面孔的有效检测。然而,这些框将有显著的重叠。

image.png

如果您不加过滤地使用这些数据,就会有多个框指示图像同一区域中检测到的面孔,如上所示。作为最终输出,我们希望每个面孔有一个单独的框。

非最大抑制

用于过滤这些框的方法称为非最大抑制(NMS),它使用IoU(交集与并集的比率)来确定重叠的框。这个过程的Java等效代码如下:

for (Integer idx1 : sortedCandidateIdx) {if (!finalCandidates.isEmpty()) {boolean hasIoUAboveThreshold = false;for (Integer idx2 : finalCandidates) {float l = Math.min(box[idx1][0], box[idx2][0]);float t = Math.min(box[idx1][1], box[idx2][1]);float r = Math.max(box[idx1][2], box[idx2][2]);float b = Math.max(box[idx1][3], box[idx2][3]);if (l>=r || t>=b) continue;float intersection = (r-l)*(b-t);float area1 = (box[idx1][2]-box[idx1][0])*(box[idx1][3]-box[idx1][1]);float area2 = (box[idx2][2]-box[idx2][0])*(box[idx2][3]-box[idx2][1]);float iou = intersection / (area1 + area2 - intersection + 0.0000001f);if (iou<iouThreshold) continue;hasIoUAboveThreshold=true;break;}if (hasIoUAboveThreshold) continue;}finalCandidates.add(idx1);
}

采用此方法,最终的候选者现在清晰地分隔成4个不同的部分。

image.png

使用结果数据

此时的实际结果数据仍然是一组在归一化空间[0,1]x[0,1]中的框坐标。我们可以使用OpenCV的方法将结果绘制到源图像上,如这里所示,或者我们可以将信息传递给任何连续的过程。

for (Integer idx : finalCandidates) {Rect rec = new Rect(new Point(box[idx][0] * width, box[idx][1] * height), new Point(box[idx][2] * width, box[idx][3] * height));Imgproc.rectangle(sourceImage, rec, color, linethickness);   
};

结论

通过Mendix ML工具包,导入和运行预训练的ONNX模型变得更加简单。Mendix为映射输入和输出数据到实际模型提供了我们已经习惯的接口类型。

您仍然需要数据预处理和后处理的专业知识。其中一些步骤在类似问题中是通用的,很有可能会有更多可以直接使用的方法。

所需的一些操作是挑战性的,但模型的集成到平台中使得快速进展和在几天内获得工作解决方案变得容易。

参考资料

1. Using ML Kit

2. Mendix ML Kit Demo

3. OpenCV modules

4. GitHub - OpenCV

关于Mendix

作为西门子Xcelerator平台的低代码引擎,Mendix正在迅速成为推动企业数字化发展的首选应用程序开发平台。Mendix让企业能够以前所未有的速度构建应用程序、促进IT团队与业务专家之间开展有意义的协作,并帮助IT团队保持对整个应用程序环境的控制。作为一直被领先的行业分析师视为“领军者和远见者”的低代码平台,Mendix是云原生的、开放的、可扩展的、敏捷的,并且经过实践验证。从人工智能和增强现实,到智能自动化和原生移动,Mendix和西门子Xcelerator已成为“数字优先”企业的中坚力量。Mendix已被46个国家的4,000多家企业采用,并建立了由30多万名开发人员组成的活跃社区,这些开发人员使用该平台创建了20多万款应用程序。

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

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

相关文章

OpenHarmony实战:帆移植案例(中)

OpenHarmony实战&#xff1a;帆移植案例&#xff08;上&#xff09; Audio服务介绍 服务节点 基于ADM框架的audio驱动对HDI层提供三个服务hdf_audio_render、hdf_audio_capture、hdf_audio_control。 开发板audio驱动服务节点如下&#xff1a; console:/dev # ls -al hdf_au…

【24年软考】信息系统项目管理师论文写作技巧(附范文10篇)

24年软考信息系统项目管理师论文写作准备&#xff1a; 论文准备时一定要紧扣考纲来进行&#xff0c;这样才能紧靠考试内容&#xff0c;不至于跑偏得不到高分。 1、多看论文范文&#xff0c;能够从别人的论文中快速熟悉写作的框架和思路。&#xff08;结尾有论文范文分享&…

数据库之DQL操作(数据查询语言)

DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录。查询关键字: SELECT。 本节介绍以下表为例&#xff1a; create table emp(id int comment 编号&#xff0c;workno varchar(10) comment 工号&#xff0c;nam…

mybatis-plus与mybatis同时使用别名问题

在整合mybatis和mybatis-plus的时候发现一个小坑&#xff0c;单独使用mybatis&#xff0c;配置别名如下&#xff1a; #配置映射文件中指定的实体类的别名 mybatis.type-aliases-packagecom.jk.entity XML映射文件如下&#xff1a; <update id"update" paramete…

rabbitmq安装延时插件

rabbitmq安装延时插件 1、下载延迟插件 在 RabbitMQ 的 3.5.7 版本之后&#xff0c;提供了一个插件&#xff08;rabbitmq-delayed-message-exchange&#xff09;来实现延迟队列 &#xff0c;同时需保证 Erlang/OPT 版本为 18.0 之后。 我这里 MQ 的版本是 3.10.0 现在去 GitH…

深入浅出 -- 系统架构之微服务标准组件及职责

我们来认识一下微服务架构在Java体系中依托哪些组件实现的。 相对于单体架构的简单粗暴&#xff0c;微服务的核心是将应用打散&#xff0c;形成多个独立提供的微服务&#xff0c;虽然从管理与逻辑上更符合业务需要。但微服务架构也带来了很多急需解决的核心问题&#xff1a; 1…

Java项目中使用事务

事务的四大特性 事务特性ACID&#xff1a;原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;、持久性&#xff08;Durability&#xff09;。 原子性是指事务包含的所有操作要么全部成功&#x…

HarmonyOS 开发-实现Swiper高度可变化效果

介绍 在很多应用中&#xff0c;swiper组件每一个page的高度是不一致的&#xff0c;所以需要swiper组件下方页面的高度跟着一起变化。 效果图预览 使用说明 向左滑动swiper组件&#xff0c;上方swiper组件高度变高&#xff0c;下方页面随着swiper的变化而平滑的变化。 实现思…

第十三届蓝桥杯C/C++大学B组真题题解(一)

1、扫雷 #include <bits/stdc.h> using namespace std; int n,m; const int N110; int g[N][N]; int dx[8]{-1,-1,-1,0,1,1,1,0}; int dy[8]{-1,0,1,1,1,0,-1,-1}; int dfs(int x,int y){int ans0;for(int i0;i<8;i){int axdx[i],bydy[i];if(a<0||a>n-1||b<0…

【RHEL】redhat yum 报错: not registered to Red Hat Subscription Management.

【RHEL】redhat yum 报错: not registered to Red Hat Subscription Management. 问题描述解决方法参考博客&#xff1a; 问题描述 使用redhat7用yum install -y dos2unix命令时出现这个错误 This system is not registered to Red Hat Subscription Management. You can use …

乳腺癌诊断的集成自注意力Transformer编码器

ETECADx: Ensemble Self-Attention Transformer Encoder for Breast Cancer Diagnosis Using Full-Field Digital X-ray Breast Images 内科医生和放射科医生建议使用多种方法来发现乳腺癌&#xff0c;包括数字乳房x线摄影(DM)、超声(US)和磁共振成像(MRI)。 CAD系统与乳腺x线…

深度学习【向量化(array)】

为什么要向量化 在深度学习安全领域、深度学习练习中&#xff0c;你经常发现在训练大量数据时&#xff0c;深度学习算法表现才更加优越&#xff0c;所以你的代码运行的非常快至关重要&#xff0c;否则&#xff0c;你将要等待非常长的时间去得到结果。所以在深度学习领域向量化…

java中使用雪花算法(Snowflake)为分布式系统生成全局唯一ID

&#xff08;全局唯一ID的解决方案有很多种&#xff0c;这里主要是介绍和学习Snowflake算法&#xff09; 什么是雪花算法&#xff08;Snowflake&#xff09; 雪花算法&#xff08;Snowflake Algorithm&#xff09;是由Twitter公司在2010年左右提出的一种分布式ID生成算法&…

有没有寄快递省钱的方法啊,尤其是搬家寄大件?

从大学开始离家&#xff0c;到读研&#xff0c;工作&#xff0c;辗转换了四五个城市了&#xff0c;大大小小搬家十几次&#xff0c;最近才发现有一个宝藏寄快递方法。 个人寄件贵是为什么呢&#xff1f;据我做物流的朋友说一般我们寄快递因为单量少&#xff0c;所以单件价格都…

Windows下Docker安装Kafka3+集群

编写 docker-compose.yaml 主要参照&#xff1a;https://www.cnblogs.com/wangguishe/p/17563274.html version: "3"services:kafka1:image: bitnami/kafka:3.4.1container_name: kafka1environment:- KAFKA_HEAP_OPTS-Xmx1024m -Xms1024m- KAFKA_ENABLE_KRAFTyes- K…

【一】学习TDengine-总结新技术学习的思考

学习TDengine-总结新技术学习的思考 概要 因业务场景需要我们开始接触时序数据库&#xff0c;于是开始根据以往的学习经验着手熟悉这一项新技术&#xff0c;学习也是一种技能&#xff0c;成功的人越容易成功&#xff0c;因为他们掌握了一套成功的方法&#xff0c;这里提到学习经…

windows 线程同步的四种方式总结

一&#xff1a;内核态下的三种同步方式&#xff1a; 一、互斥变量&#xff08;Mutex&#xff09; 互斥对象包含一个使用数量&#xff0c;一个线程ID和一个计数器。其中线程ID用于标识系统中的哪个线程当前拥有互斥对象&#xff0c;计数器用于指明该线程拥有互斥对象的次数。 创…

Vue的学习之旅-part5

Vue的学习之旅-part5 虚拟DOM的原理用JS模拟DOM结构 vue的方法、计算属性、过滤器computed:{} 计算属性computed计算属性的完全体computed计算属性和methods方法的区别&#xff1a;过滤器&#xff1a;filters:{ 多个方法 } Vuex 状态管理模式 前几篇博客: Vue的学习之旅-part1 …

【算法】第二篇 大衍数列

导航 1. 简介2. 数列特征3. 代码演示 1. 简介 大衍数列&#xff0c;来源于《乾坤谱》中对易传“大衍之数五十”的推论。主要用于解释中国传统文化中的太极衍生原理。数列中的每一项&#xff0c;都代表太极衍生过程中&#xff0c;曾经经历过的两仪数量总和。是中华传统文化中隐…

A Study of Network Forensic Investgation in Docker Environments文章翻译

A Study of Network Forensic Investgation in Docker Environments Docker环境下的网络取证研究 摘要 网络罪犯利用越来越多的技术(如虚拟机或基于容器的基础设施)进行恶意活动。 这些虚拟环境的固有动态简化了恶意服务的快速创建,并隐藏了所涉及的系统,这是以前没有的技…