当前位置: 首页 > news >正文

Milvus×EasyAi:如何用java从零搭建人脸识别应用

84a239c6063e493bb52ebc61b9be1722.png

a603cd554729439a9f7b81a06806916b.png

如何从零搭建一个人脸识别应用?不妨试试原生Java人工智能算法:EasyAi + Milvus 的组合拳。

本文将使用到的软件和工具包括:

  • EasyAi:人脸特征向量提取

  • Milvus:向量数据库用于高效存储和检索数据。

01.

EasyAi:国内人气最高的Java人工智能算法框架

作为纯java开发 Ai 应用的框架,EasyAi无任何依赖,它是一个原生Java人工智能算法框架。首先,它可以Maven一键丝滑引入我们的Java项目,无需任何额外的环境配置与依赖,做到开箱即用。再者,它既有一些我们已经封装好的图像目标检测及人工智能客服的模块,也提供各种深度学习,机器学习,强化学习,启发式学习,矩阵运算,求导函数,求偏导函数等底层算法工具。开发者可以通过简单的学习,就能完成根据自身业务,深度开发符合自己业务的小微模型。

02.

EasyAi-Face:基于Easy-Ai的人脸识别应用

一,生成人类平均脸,将所有人脸样本样本缩放到统一尺寸后,多余的上下截断,不足的进行补0,所有像素通道求和后获取平均数,将样本输出生成平均脸。

二,通过事先训练好的人脸定位fastYolo模型,对目标照片进行一次定位,并设置一个阈值,只有当可信度超过该阈值时才被认为是人脸。

三,获取目标照片中可信度最高的人脸定位框,基于该定位进行人脸位置的二次修正。

二次修正方案:

  • 通过粒子群,设置四个特征维度寻求最优解,它们分别是人脸位置左上角的x与y坐标与宽高。自适应函数返回值设置为最小值最优。xy与宽高四维粒子调整活动范围,上下限制为一次定位坐标与宽高的+-50像素的范围(自行可调)。

  • 适应函数计算流程为通过四个维度粒子锁定的坐标将人脸截取下来,将它与先前获取的平均脸按照之前的缩放方案,再次缩放到指定的一个更小的尺寸,并将它们的灰度通道通过softMax将整个矩阵的所有数值概率化。

  • 对比平均脸与粒子此时锁定人脸灰度概率图像的欧式距离,并返回。让粒子探索(在指定迭代次数中)最小值最优解。

四,获取人脸特征,获取最后粒子寻找的最优坐标,根据该坐标将图像截取下来,并截取其从上到下高度的0.7倍的图像位置(将嘴部扔掉,嘴部的稳定性比较差),获取此时图像的LBP局部二值化纹理特征。

03.

EasyAi-Face + Milvus搭建人脸识别应用

3.1 提取人脸特征

引入依赖

<dependency><groupId>org.dromara.easyai</groupId><artifactId>seeFace</artifactId><version>1.0.5</version></dependency>

初始化Face

@Beanpublic Face face(FaceConfig faceConfig ){if (StringUtils.isNotBlank(faceConfig.getAvgFace()) && StringUtils.isNotBlank(faceConfig.getFaceModel())){return FaceFactory.getFace(faceConfig.getAvgFace(), faceConfig.getFaceModel());}return FaceFactory.getFace();}

提取人脸特征

private List<Float> getFloats(InputStream inputStream) {ThreeChannelMatrix m = Picture.getThreeMatrix(inputStream, false);ErrorMessage errorMessage = face.look(m, idWorker.nextId(), 30);final Matrix feature = errorMessage.getFaceMessage().getFeature();return MatrixUtil.matrixToFloatList(feature);}

3.2 存到向量库

public void initUserVector(UserDTO userDTO, List<Float> features) {List<String> names = Collections.singletonList(userDTO.getUserName());List<Long> userIds = Collections.singletonList(userDTO.getUserId());List<String> getFaceUrl = Collections.singletonList(userDTO.getFaceUrl());List<String> getFaceFeatureUrl = Collections.singletonList(userDTO.getFaceFeatureUrl());List<List<Float>> vectors = Collections.singletonList(features);List<Field> fields = new ArrayList();fields.add(new Field("vector", vectors));fields.add(new Field("face_url", getFaceUrl));fields.add(new Field("face_feature_url", getFaceFeatureUrl));fields.add(new Field("user_id", userIds));fields.add(new Field("user_name", names));InsertParam insertParam = InsertParam.newBuilder().withCollectionName(milvusConfig.getCollectionName()).withFields(fields).build();this.milvusClient.insert(insertParam);}

3.3 【识别人脸】人脸特征L2相似性查找

public List<UserDTO> search(List<Float> floatList, Integer topK) {final List<SearchResultsWrapper.IDScore> idScoreList = vectorService.search(floatList, topK);List<UserDTO> list = new ArrayList<>();idScoreList.forEach(idScore -> {UserDTO imageDTO = new UserDTO();final float score = idScore.getScore();final Map<String, Object> fieldValues = idScore.getFieldValues();imageDTO.setAutoId(Long.valueOf(String.valueOf( fieldValues.getOrDefault("Auto_id", "-1"))));imageDTO.setUserId(Long.valueOf(String.valueOf( fieldValues.getOrDefault("user_id", "-1"))));imageDTO.setUserName(String.valueOf((fieldValues.getOrDefault("user_name", ""))));imageDTO.setFaceUrl(String.valueOf((fieldValues.getOrDefault("face_url", ""))));imageDTO.setFaceFeatureUrl(String.valueOf((fieldValues.getOrDefault("face_feature_url", ""))));imageDTO.setScore(Math.sqrt(score));list.add(imageDTO);});return list;}

04.

总结

本文展示了如何使用 EasyAi 和 Milvus 搭建一个人脸识别应用。通过结合Java生态EasyAi和Milvus向量搜索的优势,我们可以快速的使用java搭建自己的人脸识别的项目。我们希望这篇文章对您有所帮助。同时,我们鼓励您在自己的项目中使用EasyAi和向量搜索,探索更多可能性。本文涉及的代码可以通过 Gitee 获取:Easy-Ai-Face(https://gitee.com/fushoujiang/easy-ai-face)

推荐阅读

3e269c480421977466a754d1077a5b18.png

0b7d90a603fad85865cce270162ff81a.png

c783fe4a28d6c1849d52a3051f754538.png

a0321a6039d460d790884d957d0be4fc.png

相关文章:

Milvus×EasyAi:如何用java从零搭建人脸识别应用

如何从零搭建一个人脸识别应用&#xff1f;不妨试试原生Java人工智能算法&#xff1a;EasyAi Milvus 的组合拳。 本文将使用到的软件和工具包括&#xff1a; EasyAi&#xff1a;人脸特征向量提取Milvus&#xff1a;向量数据库用于高效存储和检索数据。 01. EasyAi&#xff1a;…...

Dockerfile 实战指南:解锁高效容器化开发

一、Dockerfile 简介 Dockerfile 是构建镜像的文本文件&#xff0c;通过一系列指令描述镜像构建过程&#xff0c;构建操作由 Docker daemon 进行&#xff0c;它会先验证语法&#xff0c;然后逐一运行指令&#xff0c;每次生成一个新的镜像层&#xff0c;直到构建出最终的镜像。…...

【每日学点鸿蒙知识】混淆配置、主线程处理大量数据、客户端拖拽效果、三方网站加载样式、List警告问题

1、HarmonyOS API升级之后缺少混淆配置文件&#xff1f; 可参考以下文档&#xff1a; 混淆配置&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-build-obfuscation-V5 混淆规则&#xff1a;https://gitee.com/openharmony/arkcompiler_ets…...

ChatGPT-4助力学术论文提升文章逻辑、优化句式与扩充内容等应用技巧解析。附提示词案例

目录 1.扩写&#xff08;expansion/paraphrasing&#xff09; 2.优化&#xff08;optimization&#xff09; 3.缩写&#xff08;optimization&#xff09; 4.提取关键词&#xff08;keyword extraction&#xff09; 5.短语转换&#xff08;phrase transformation&#xff…...

Android TextView 添加图标并实现换行

图文混排。 binding.apply {val spannable = SpannableString(" " + "Kotlin 是 Android 官方推荐的编程语言。")val drawable: Drawable = ContextCompat.getDrawable(this@DemoMainXmlActivity,R.mipmap.ic_title_d)!!drawable.setBounds(0, 0, drawabl…...

matplotlib pyton 如何画柱状图,利用kimi,直接把图拉倒上面,让他生成

要绘制类似于您提供的图像的柱状图&#xff0c;您可以使用Python中的Matplotlib库&#xff0c;这是一个非常流行的绘图库。以下是一个简单的示例代码&#xff0c;展示如何使用Matplotlib来创建一个类似的柱状图&#xff1a; python import matplotlib.pyplot as plt import nu…...

如何保证mysql数据库到ES的数据一致性

1.同步双写方案 在代码中对数据库和ES进行双写操作&#xff0c;确保先更新数据后更新ES。 优点&#xff1a; 数据一致性&#xff1a;双写策略可以保证在MySql和Elasticsearch之间数据的强一致性&#xff0c;因为每次数据库的变更都会在Elasticsearch同步反映。实时性&#xf…...

安装MongoDB,环境配置

官网下载地址&#xff1a;MongoDB Shell Download | MongoDB 选择版本 安装 下载完成双击打开 点击mongodb-windows-x86_64-8.0.0-signed 选择安装地址 检查安装地址 安装成功 二.配置MongoDB数据库环境 1.找到安装好MongoDB的bin路径 复制bin路径 打开此电脑 -> 打开高级…...

家用无线路由器的 2.4GHz 和 5GHz

家中的无线路由器 WiFi 名称有两个&#xff0c;一个后面带有 “5G” 的标记&#xff0c;这让人产生疑问&#xff1a;“连接带‘5G’的 WiFi 是不是速度更快&#xff1f;” 实际上&#xff0c;这里的 “5G” 并不是移动通信中的 5G 网络&#xff0c;而是指路由器的工作频率为 5G…...

我的tensorboard

1.Tensorboard 2.Tensorboard的使用 导入tensorboard并创建SummaryWriter 添加标量数据 添加图片数据 直方图 模型可视化 3.代码使用 模型可视化 # 记录模型结构 dummy_input torch.randn(1, 3, 224, 224).to(device) # 根据你的模型输入尺寸调整 writer.add_graph(model…...

Quartz 相关线程

​ 我们在前面文章中说到过Quartz涉及到的线程&#xff0c;但是散落在几篇文章中&#xff0c;不好找。而Quartz涉及到的线程对于理解Quartz也比较重要&#xff0c;所以今天专门提取出来单独说一下。 Quartz中的主要线程&#xff1a; 任务调度线程QuartzSchedulerThread 任务执…...

【QED】爱丽丝与混沌的无尽海

文章目录 题目题目描述输入输出格式数据范围测试样例 思路代码复杂度分析时间复杂度空间复杂度 题目 题目链接&#x1f517; 题目描述 如图所示&#xff0c;爱丽丝在一个3x3的迷宫之中&#xff0c;每个方格中标有 1 − 9 1-9 1−9各不相同的数字&#xff0c;爱丽丝可以从一格…...

IO模型学习

背景知识 Socket 套接字。 客户端和服务端通信时&#xff0c;客户端需要数据出口&#xff0c;服务端需要数据入口&#xff0c;这两个出入口就是Socket。数据接收方新建socket后需要绑定ip和端口号&#xff0c;这样客户端才能链接上socket。连接的过程就是 三次握手 FD file …...

Doxygen 使用指南

Doxygen 是一个文档生成工具&#xff0c;可以从源代码中的注释生成高质量的文档&#xff0c;支持多种编程语言&#xff08;如 C/C、Python、Java 等&#xff09;。以下是 Doxygen 的基本使用方法。 1. 安装 Doxygen 1.1 下载 Doxygen 访问 Doxygen 官网。根据操作系统选择合适…...

设计模式与游戏完美开发(2)

更多内容可以浏览本人博客&#xff1a;https://azureblog.cn/ &#x1f60a; 该文章主主题内容均来自《设计模式与游戏完美开发》—蔡升达 第二篇 基础系统 第四章 游戏主要类——外观模式&#xff08;Facade&#xff09; 一、游戏子功能的整合 一个游戏程序常常由内部数个不…...

Coroutine 基础三 —— 结构化并发(二)

1、协程的结构化异常管理 如果一个协程抛异常&#xff0c;它所在的整个协程树上的其他协程&#xff08;向上是父协程到根协程&#xff0c;向下是所有后代协程&#xff09;都会被取消。因此协程发生异常的后果是十分严重的。 先讲原理&#xff0c;再说解决方案。 协程异常的处…...

GXUOJ-算法-第一次作业

1.整数划分 问题描述 GXUOJ | 整数划分 题解 #include<bits/stdc.h> using namespace std; const int N1010,mod1e97;int n; int f[N];int main(){cin>>n;f[0]1;for(int i1;i<n;i){for(int ji;j<n;j){f[j](f[j]f[j-i])%mod;}}cout<<f[n]; } 2.汉诺塔…...

Springboot项目Druid运行时动态连接多数据源的功能

项目支持多数据库连接是个很常见的需求&#xff0c;这不仅是要在编译前连已经知道的多个数据库&#xff0c;有时还要在程序运行时连后期增加的多个数据源来获得数据。 一、编译前注册数据库连接 1.引入依赖包 <!-- springboot 3.x --><dependency><groupId&g…...

字符串匹配——KMP算法

前言 刷到字符串匹配的力扣题了【28. 实现 strStr() 】&#xff0c;这题简单吧用库函数做就可以&#xff0c;说难吧&#xff0c;就得引出大名鼎鼎的线性匹配算法——KMP。 目录 KMP 算法背景与原理算法优势 前缀表1. 构建Next数组2. 搜索匹配 KMP 算法背景与原理 KMP&#x…...

Qt开发技术【下拉复选框 MultiSelectComboBox 自定义全选项】

继承ComboBox完成下拉复选框 自定义全选项 效果图 整个控件继承于QCombobox类。主要修改QLineEdit、QListWidget这两部分&#xff0c;QComboBox提供如下接口&#xff0c;可以将这两部分设置为新建的QLineEdit、QListWidget对象 CMultiSelectComboBox::CMultiSelectComboBo…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...