爱智EdgerOS之深入解析AI图像引擎如何实现AI视觉开发

一、前言

  • AI 视觉是为了让计算机利用摄像机来替代人眼对目标进行识别,跟踪并进一步完成一些更加复杂的图像处理。这一领域的学术研究已经存在了很长时间,但直到 20 世纪 70 年代后期,当计算机的性能提高到足以处理图片这样大规模的数据时,计算机视觉才得到了正式的关注和发展。
  • 现在 AI 视觉已经在我们的生活中无处不在,从日常使用的二维码到人脸识别直至更专业的病理分析。AI 视觉的应用所渗透到的领域远比我们想象的更加广泛。虽然 AI 视觉的应用已经随处可见,但如果想要自己去开发一套属于自己的 AI 视觉应用,对于一个非专业领域的开发者还是非常复杂的,单从最基础的算法训练就要消耗掉大量的精力与时间。
  • EdgerOS 系统则内置了多种不同方向的 AI 引擎,使开发者可以实现快速实现 AI 视觉领域的开发,极大的降低了开发周期。开发者可以根据自己的需求对不同 AI 引擎进行组合达到自己想要的业务实现。本文将带领大家一起了解 EdgerOS 中常用的两款 AI 引擎。

二、FaceNN

  • FaceNN 是 EdgerOS 所提供的一个针对人脸识别的 AI 处理引擎,它可以从视频流或者图片中捕捉到人脸的具体位置,还可以根据人脸的特征来分析出对应人物的特征信息如:年龄、性别、情感等一些具体信息。
  • FaceNN 引擎封装在 “facenn” 模块中,可以通过以下方式来导入:
const facenn= require('facenn');
  • FaceNN 引擎提供了极简的接口,这使得开发者可以更加快速的实现关于人脸的 AI 处理,同时也降低了巨大的学习成本。
  • 首先需要明确一下被识别的图像格式,目前 FaceNN 引擎支持如下格式:
类型说明
facenn.PIX FMT RGB24RGB24 pixel format
facenn.PIX FMT BGR2RGB24BGR24 to RBG24 pixel format
facenn.PIXFMTGRAY2RGB24Grayscale to RGB24 pixel format
facenn.PIX FMT RGBA2RGB24RGBA to RGB24 pixel format
  • facenn.detect(videoBuf, attribute[, quick])
    • attribute {Object} 图像格式
      • width {Integer} 图像宽度
      • height {Integer} 图像高度
      • pixelFormat {Integer} 图像格式
    • quick {Boolean} 是否启用快速模式
  • 返回信息:
    • score {Number} 人脸的覆盖率
    • x0 {Integer} 左上角 x 的位置
    • y0 {Integer} 左上角 y 的位置
    • x1 {Integer} 右下角 x 的位置
    • y1 {Integer} 右下角 y 的位置
    • area {Number} Area,非快速模式
    • regreCoord {Array} RegreCoord,非快速模式
    • landmark {Array} Landmark,非快速模式
  • facenn.detect 可以识别出一帧图像数据中的人脸个数以及人脸所在图像中的位置。
  • facenn.feature(videoBuf, attribute, faceInfo[, extra])
    • videoBuf {Buffer} 图像格式
    • attribute {Object} 图像属性
      • width {Integer} 图像宽度
      • height {Integer} 图像高度
      • pixelFormat {Integer} 图像格式
    • extra {Object} 需要扩展的人脸信息 default: undefined
  • 返回信息:
    • keys {Array} Face keys
    • male {Boolean} 性别, 需要在扩展中选择
    • age {Integer} Age, 需要在扩展中选择
    • emotion {String} Emotion, 需要在扩展中选择
    • emotion 可分辨情绪包括: angry,disgust,fear,happy,sad,surprise,neutral
    • live {Number} 存活率,需要在扩展中选择
  • facenn.feature 可以识别出一张人像的具体信息,例如性别,情绪年龄等。
  • facenn.compare(faceKeys1, faceKeys2)
    • faceKey1 {Object} Face keys 1
    • faceKey2 {Object} Face keys 2
  • 返回信息:
    • 相似值 0.0 ~ 1.0
    • facenn.compare 可以比对出两张人脸信息的相似值。
  • 接下来用一下两张图片来尝试使用 FaceNN 引擎,读取其中的特征信息:

在这里插入图片描述
在这里插入图片描述

const imagecodec = require('imagecodec'); // 图片解析模块
const facenn = require('facenn'); 


function facennHandel(imagePath, imagePath2) {
    const image1 = imagecodec.decode(imagePath, imagecodec.COMPONENTS_RGB)
    const imageInfo1 = imagecodec.info(imagePath)
    const videoAttrFacenn = { width: imageInfo1.width, height: imageInfo1.height, pixelFormat: facenn.PIX_FMT_RGB24 }

    const faceInfos = facenn.detect(image1.buffer, videoAttrFacenn);
    const facennFeature = facenn.feature(image1.buffer, videoAttrFacenn, faceInfos[0], {
        male: true,
        age: true,
        emotion: true,
        live: true
    })
    console.log(`image1.png  male:${facennFeature.male} age:${facennFeature.age} emotion:${facennFeature.emotion} live:${facennFeature.live}`)

    const image2 = imagecodec.decode(imagePath2, imagecodec.COMPONENTS_RGB)
    const imageInfo2 = imagecodec.info(imagePath2)
    const videoAttrFacenn2 = { width: imageInfo2.width, height: imageInfo2.height, pixelFormat: facenn.PIX_FMT_RGB24 }
    const faceInfos2 = facenn.detect(image2.buffer, videoAttrFacenn2);
    const facennFeature2 = facenn.feature(image2.buffer, videoAttrFacenn2, faceInfos2[0], {
        male: true,
        age: true,
        emotion: true,
        live: true
    })
    console.log(`image2.png  male:${facennFeature2.male} age:${facennFeature2.age} emotion:${facennFeature2.emotion} live:${facennFeature2.live}`)
    
    const compareNum = facenn.compare(facennFeature.keys, facennFeature2.keys)
    console.log(compareNum)
}

facennHandel('/image/image1.png', '/image/image2.png')

// 输出如下:
// [JSRE-CON]image1.png  male:false age:21 emotion:neutral live:0.9843575954437256
// [JSRE-CON]image2.png  male:true age:58 emotion:sad live:0.33667701482772827
// [JSRE-CON]-0.1453045904636383

三、ThingNN

  • ThingNN 是 EdgerOS 可以从视频流或者图片中捕捉到具体事物,分别标记事务所在图片中的具体位置。
  • ThingNN 引擎封装在 “thingnn” 模块中,可以通过以下方式来导入:
const facenn= require('thingnn');
  • 同样也需要明确一下被识别的图像格式,目前 ThingNN 引擎支持如下格式:
类型说明
thingnn.PIX FMT_ RGB24RGB24 pixel format
thingnn.PIX_FMT_BGR2RGB24BGR24 to RBG24 pixel format
thingnn.PIX FMT GRAY2RGB24Grayscale to RGB24 pixel format
thingnn.PIX FMT RGBA2RGB24RGBA to RGB24 pixel format
  • 接下来看看 ThingNN 接口提供了那些接口:
  • thingnn.detect(videoBuf, attribute)
    • videoBuf {Buffer} 图像格式
    • attribute {Object} 图像属性
    • width {Integer} 图像宽度
    • height {Integer} 图像高度
    • pixelFormat {Integer} 图像格式
  • 返回信息:
    • className{Array} Face keys
    • prob{Boolean} 性别, 需要在扩展中选择
    • x0 {Integer} 左上角 x 的位置
    • y0 {Integer} 左上角 y 的位置
    • x1 {Integer} 右下角 x 的位置
    • y1 {Integer} 右下角 y 的位置
  • 目前 ThingNN 模块所支持可识别的类型都有:
background, aeroplane, bicycle, bird, boat,bottle, bus, car, cat, chair,cow, diningtable, dog, horse,motorbike,person, pottedplant,sheep, sofa, train, tvmonitor
  • thingnn.detect 可以获取到图片中事物的类别以及所在图像中的位置。
  • thingnn.identify(videoBuf, attribute, thingInfo)
    • videoBuf {Buffer} 图像格式
    • attribute {Object} 图像属性
    • width {Integer} 图像宽度
    • height {Integer} 图像高度
    • pixelFormat {Integer} 图像格式
    • thingInfo {Object} 事务对象
  • 返回信息:具体事物的名称,thingnn.identify 可以获取到具体 thinginfo 的类型名称。
  • 以下图为例子作为演示:

在这里插入图片描述

const imagecodec = require('imagecodec'); // 图片解析模块
const facenn = require('facenn'); 


function licplatennHandel(imagePath) {
const imageInfo = imagecodec.info(imagePath)
const imageBuf= imagecodec.decode(imagePath, imagecodec.COMPONENTS_RGB).buffer
let videoAttrThingnn = { width: imageInfo.width, height: imageInfo.height, pixelFormat: thingnn.PIX_FMT_BGR24 }
    const thingInfos = thingnn.detect(imageBuf, videoAttrThingnn);
    thingInfos.forEach((thingInfo, index) => {
        const thingName = thingnn.identify(imageBuf, videoAttrThingnn, thingInfo);
        console.log(index,thingInfo.className, thingName)
    })
}

licplatennHandel('/image/dog.png')

// 输出如下:
// [JSRE-CON]0 dog Labrador retriever

四、ImageCodec

  • FaceNN 模块在单独使用时是处理视频流中的人脸信息的,现在假设我们的场景是一个智能门锁,首先需要录入人脸信息,添加为合法的开锁用户,门锁摄像头再捕获视频流检测出人脸信息进行核对,校验通过则打开门锁。在录入人脸信息的时候,需要将多张人脸照片处理成流信息提供给 FanceNN 模块进行解析,ImageCodec 模块刚好就可以胜任此工作。
  • ImageCodec 模块提供了对多种图像格式进行编码和解码方法,包括:PNG,JPG,BMP,TGA,HDR,接下来具体看一下,如何通过 ImageCodec 处理图片数据。
const imagecodec = require('imagecodec')

① 区分带通道的图片

  • 在对图片进行解码的时候需要区别处理带通道的 PNG 图片,ImageCodec 模块上的 decode 方法支持传入第二个可选参数:
    • imagecodec.decode(path[, opt]):
const image = imagecodec.decode('./test.png', {components: imagecodec.COMPONENTS_RGB_ALPHA})
  • opt 的配置选项 components 可以指定以下值来区别处理不同格式的图片:
定义描述
imagecodec.COMPONENTS_DEFAULT0使用图片的默认值
imagecodec.COMPONENTS_GREY1单字节灰度图像
imagecodec.COMPONENTS_GREY_ALPHA2带有 Alpha 通道的灰度图像
imagecodec.COMPONENTS_RGB3三字节 RGB 图像
imagecodec.COMPONENTS_RGB_ALPHA4带有 Alpha 通道的 RGB 图像
  • 如何判断一个图片的格式,我们知道计算机实际并不是根据后缀来判断文件类型的,事实上,有个东西叫魔法数字(Magic Number),它是某一类型的文件的头一个或几个字节的内容,可以根据这个来判断传入的图片文件是什么类型的:
const fs = require('fs')
const imagecodec = require('imagecodec')
const imageBuffer = fs.readFile('./human.jpg')

let type = ''
const arr = (new Uint8Array(picture)).subarray(0, 4)
const headerString = arr.reduce((acc, cur) => acc+cur.toString(16), '')
switch (headerString) {
  case "89504e47":
    type = "png";
    break
  case "47494638":
    type = "gif";
    break
  case "ffd8ffe0":
  case "ffd8ffe1":
  case "ffd8ffe2":
    type = "jpg"
    break
  default:
    console.log('[mime-type] not png/gif/jpg.')
    break
}
  • 将图片文件的前 4 个字节(4 个字节的长度已经足够判断出图片的类型了)拿出来进行判断,一般拍照上传的照片是 JPG 或 PNG,所以这里只需要判断出图片是否是带有 ALPHA 通道的图片即可。

② decode 方法解析图片文件

  • 上面判断出图片类型之后,就可以通过 decode 方法解码图片文件:
const bitmap = imagecodec.decode(picture, {
  components: type === 'png' ? imagecodec.COMPONENTS_RGB_ALPHA : imagecodec.COMPONENTS_RGB
})
  • decode解析得到的 bitmap 为一个图像像素对象,它包含 width,height,components,buffer 4个属性,也正是 FaceNN 所需要的内容。

③ 解析图片中的人脸信息

  • 这里跟 AI 识别的内容基本一致:
const facenn = require('facenn')

const faces = facenn.detect(bitmap.buffer, {
  width: bitmap.width,
  height: bitmap.height,
  pixelFormat: type === 'png' ? facenn.PIX_FMT_RGBA2RGB24 : facenn.PIX_FMT_RGB24
}, true)
  • 此时得到的 faces 内容就是识别之后的人脸特征信息,从图片中获取面部信息的功能就完成。

④ 封装成包

  • 这个功能已经封装成一个 jsre 包上传到了 npm 仓库,可以通过以下方式进行安装和使用:
npm install @edgeros/ofii

const getFaceFeature = require('@edgeros/ofii')
const imageBuffer = fs.readFile('./hunman.png')
const keys = getFaceFeature(imageBuffer)
// 如果没有检测到人脸信息则返回 []
  • 在不同的场景中我们需要对图片进行编码解码,来配合完成更加复杂的功能和服务。EdgerOS 在网络应用,人工智能等场景提供了丰富的接口,能够极大简化开发流程。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有源滤波装置在水处理行业配电系统中的应用

摘要:在水处理行业供配电系统中,涉及曝气风机、提升泵、污泥脱水设备等负荷设备,导致异步电动机产生较多无功功率和大量的谐波,使系统功率因数下降,以及谐波对配电系统、负载产生较大的危害。就此,水处理行…

53. Protocol buffer 的Go使用

文章目录 一、介绍二、安装三、protoc3语法1、 protoc3 与 protoc2区别2、proto3生成go代码包Message内嵌Message字段单一标量字段单一message字段可重复字段slicemap字段枚举 一、介绍 Protobuf是Google旗下的一款平台无关,语言无关,可扩展的序列化结构…

time模块(python)

一.sleep休眠 [rootrhel8 day04]# vim demo01_time.py import time def banzhuan():print("搬砖")time.sleep(3.5) #让程序休眠3.5秒print("结束")banzhuan()[rootrhel8 day04]# python3 demo01_time.py 搬砖 结束运行时,会发现程序中间暂停…

征途漫漫:汽车MCU的国产替代往事

01.西雁东飞,南下创业 1985年,山东大学物理系毕业的周生明加入878厂(“北霸天”)参与MOS电路研发,随后几年,大洋彼岸的英特尔相继推出CPU 386\486、奔腾系列等产品。在摩尔定律的凸显、进口和走私的剧烈冲…

js/jQuery常见操作 之各种语法例子(包括jQuery中常见的与索引相关的选择器)

js/jQuery常见操作 之各种语法例子(包括jQuery中常见的与索引相关的选择器) 1. 操作table常见的1.1 动态给table添加title(指定td)1.1.1 给td动态添加title(含:获取tr的第几个td)1.1.2 动态加工…

RocketMQ-RocketMQ高性能核心原理(流程图)

1.NamesrvStartup 2.BrokerStartup 3. DefualtMQProducer 4.DefaultMQPushConsumer

Unity-Shader - 2DSprite描边效果

实现一个简单的2D精灵图描边效果,效果如下 实现思路: 可以通过判断该像素周围是否有透明度为 0的值,如果有,则说明该像素位于边缘。 所以我们需要打开alpha blend,即: Blend SrcAlpha OneMinusSrcAlpha&am…

Java 11 到 Java 21:无缝迁移的可视化指南

迁移到 Java 21 的理由 在我们探索从 Java 11 迁移到 Java 21 的必要性的旅程中,我们深入研究了四个关键类别,并强调了这一转变的重要性。每个方面都至关重要,共同为采用最新版本的 Java 编程语言打造了一个引人注目的案例。 1. 安全性&#…

【数据结构(九)】线索化二叉树(3)

文章目录 1. 前言——问题引出2. 线索二叉树的基本介绍3. 线索二叉树的应用案例3.1. 思路分析3.2. 代码实现 4. 遍历线索化二叉树4.1. 代码实现 1. 前言——问题引出 问题:     将数列 {1, 3, 6, 8, 10, 14 } 构建成一颗二叉树. (n17个空指针域&…

【数据挖掘】国科大苏桂平老师数据库新技术课程作业 —— 第三次作业

part 1 设计一个学籍管理小系统。系统包含以下信息: 学号、学生姓名、性别、出生日、学生所在系名、学生所在系号、课程名、课程号、课程类型(必修、选修、任选)、学分、任课教师姓名、教师编号、教师职称、教师所属系名、系号、学生所选课…

前端:如何让background背景图片进行CSS自适应

在设置login背景时,找到了一张这样的图片: 但是设置成login背景时,如果没有做一些css适应设置,图片就变样了,变成了这样: 严重变形了,这就造成了一种理想与现实的差距。 若想解决这个自适应问题…

西工大网络空间安全学院计算机网络实验五——ACL配置

实验五、ACL配置 一. 实验目的 1. 掌握ACL的基本配置方法 二. 实验内容 1. 基于如下图所示的拓扑图,对路由器进行正确的RIP协议配置; ​ 首先引入3台2811 IOS15型号的路由器、3台2950-T24型号的交换机、4台PC-PT型号的PC机、两台Server-PT型号的服务…

Java:字节流 文件输出与读入方法 并 实现文件拷贝

文章目录 字节 流FileOutputStream换行 与 续写FileInputstream实现 文件拷贝(字节数组 读入方法)字节流 编码 字节 流 FileOutputStream 创建对象,指定位置(产生数据传输通道) 参数可以是File对象,也可以…

蓝桥杯日期问题

蓝桥杯其他真题点这里👈 注意日期合法的判断 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Main{static int[] days {0,31,28,31,30,31,30,31,31,30,31,30,31};static BufferedReader in new Buf…

功能强大的屏幕录制和剪辑工具Camtasia Studio 2024 中文版

Camtasia Studio 2024 是一款功能强大的屏幕录像工具,集视频录制、剪辑、编辑和播放于一体的多功能屏幕录制软件,Camtasia Studio 2024操作简单,它能够轻松为您将屏幕上的所有声音、影音、鼠标移动的轨迹和麦克风声音全部录制下来&#xff0c…

[足式机器人]Part2 Dr. CAN学习笔记-数学基础Ch0-9阈值选取-机器视觉中应用正态分布和6-sigma

本文仅供学习使用 本文参考: B站:DR_CAN Dr. CAN学习笔记-数学基础Ch0-9阈值选取-机器视觉中应用正态分布和6-sigma 5M1E——造成产品质量波动的六因素 人 Man Manpower 机器 Machine 材料 Material 方法 Method 测量 Measurment 环境 Envrionment DMAI…

AlexNet

概念 过拟合:根本原因是特征维度过多,模型假设过于复杂,参数过多,训练数据过少,噪声过多,导致拟合的函数完美的预测训练集,但对新数据的测试集预测结果差。 过度的拟合了训练数据,而没有考虑到…

算法专题一:双指针

算法专题一:双指针 一:移动零1.GIF题目解析: 二:复写零2.GIF题目解析: 三:快乐数3.GIF题目解析: 四:装水最多容器:4.GIF题目解析: 五:有效三角形的…

0007Java程序设计-ssm基于微信小程序的在线考试系统

文章目录 **摘要**目 录系统实现开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅🐧裙:776871563 摘要 网络技术的快速发展给各行各业带来了很大的突破,也给各行各业提供了一种新的管理技术,基于微信小程序的在线考试…