RK3399上的Tengine实践笔记

TengineKit_Demo_Identity_Protection 使用人脸关键点算法实现Android手机端人脸匿名功能 什么是人脸匿名(Face Anonymization) 随着人脸识别技术的普及,人脸数据的隐私问题也越来越受到关注,针对个人保护的研究也陆续出现。总体上有以下几个方向 篡改输入人脸识别系统的图像。 生成式对抗网络(GAN)来匿名某人的照片或视频。 直接模糊人脸识别到的人脸 本文主要讲第3点,讲讲如何使用移动端人脸关键点算法实现人脸匿名功能。这种方法对设备要求低,代码简单易懂,修改后就可直接落地。 下图就是最终想实现的功能 什么是人脸关键点算法(脸部地标) 人脸关键点检测是人脸相关算法中的关键一环,它是人脸识别,表情分析,3D人脸重建,表情驱动3D动画等一系列人脸相关问题的替代。 我们将使用TengineKit来实现人脸匿名功能 TengineKit 免费移动端实时人脸212关键点SDK。是一个易于集成的人脸检测和人脸关键点SDK。它可 立即下载

目录

0. 目的

1. 搭建环境

2. TengineKit Demo项目结构

3. 问题及解决


0. 目的

对RK3399单板的HDMI_IN输入(模拟Camera)进行人脸识别并对识别结果进行模糊化处理。

1. 搭建环境

1.1 安装Android Studio

我下的是这个android-studio-ide-201.6953283-linux.tar.gz,下载地址找不到了。

1.2 下载TengineKit

参考文章链接:

知乎:《用开源212点人脸关键点实现Android人脸实时打码》

极术社区:《用开源212点人脸关键点实现Android人脸实时打码》

Github源码链接

git clone https://github.com/OAID/TengineKit.git

1.3 设置AndroidStudio环境

·  第一个比较坑的就是gradle的同步地址要更新以下,可参考。

· 第二个就是设置SDK,我用的是安卓7.1,File --- settings --- Appearance...  --- Android SDK设置如下:

· build.gradle设置如下:(按说targetSdkVersion应该是25才对,但不知道为什么28也可以,有空再搞清楚这几个SdkVersion 的关系)

2. TengineKit Demo项目结构

整个项目文件结果如下图。水平有限说不出来个啥。

  • CameraEngine.java就是根据前后摄像头的配置设置了以下相机的旋转角度,但是因为RK3399的HDMI_IN比较特殊,虽然camera id为0(facing back)但是感觉这个facing back传递不到后面的配置中。
  • CameraConnectionFragment.java里好像最重要的就是下面这个方法了( protected static Size chooseOptimalSize),作用就是选一个可以根据设置的预览分辨率大小最优的长宽比。
  • 改的最多的是LegacyCameraConnectionFragment和ClassifierActivity两个类,前者功能主要是“完成Camera所支持的预览分辨率的读取、选取和配置”、“完成Camera的preview方向、申请preview图像的回调buffer”等功能。后者主要是调用TengineKit的jar(aar)包、根据人脸数据对图像进行模糊处理等。
  • utils下的是图像类的一些处理方法,如高斯模糊等。

3. 问题及解决

个人猜测:TengineKit在设计之初是为了手机(竖屏)使用的,因此默认build出来的版本,输出的图像是顺时针旋转了90°的,如下:

RK3399终端的屏幕是横屏(按网上很多同学的说法就是0°,但不知为何我把所有的旋转都去掉,识别率几乎等于0,我猜测模型训练的时候跟相机/人脸图片的角度有关系)

我们需要的是一个横屏的画面。改所有的rotation设置貌似都无效,那就只能老老实实地沉下心来学习别人的代码了。此处略去一段光阴。。。。。。。

最终有以下几个确认点:

1. TengineKit的输入图像有角度限制,否则识别率很低。对于0°横置的后置Camera设备,TengineKit的输出(主要说的是faceLandmarks.get(i).getBoundingBox()方法返回的Rect对象的位置)是“水平镜像后、顺时针转90°、并作宽高比调整后”的结果。

2. 对Bitmap的后处理需要根据TengineKit的输出行为做相应的改动。如我们拿到TengineKit的输出(faceLandmarks.get(i).getBoundingBox()方法返回的Rect对象)后,需要逆时针转90°(与宽高比转换一起完成),然后再做一个水平mirror的处理才能得到我们正确的结果。

根据这两个发现,一共修改了LegacyCameraConnectionFragment.java和ClassifierActivity.java两个文件。代码如下:

  • LegacyCameraConnectionFragment.java
public void onSurfaceTextureAvailable(final SurfaceTexture texture, final int width, final int height) {
......
......
// camera.setDisplayOrientation(90);    // original
   camera.setDisplayOrientation(0);     // updated
......
......
// camera.addCallbackBuffer(new byte[ImageUtils.getYUVByteSize(s.height, s.width)]); // original
// textureView.setAspectRatio(s.height, s.width); // original
camera.addCallbackBuffer(new byte[ImageUtils.getYUVByteSize(s.width, s.height)]);// updated
textureView.setAspectRatio(s.width, s.height);  //updated

            camera.startPreview();
        }
  • ClassifierActivity.java
 public void drawCallback(final Canvas canvas) {
    if(testBitmap != null){
        canvas.drawBitmap(testBitmap, 0,0, circlePaint);
        }
    if(faceLandmarks != null){
        for (int i = 0; i < faceLandmarks.size(); i++) {
            Rect r = Transform_anticlock_90deg(faceLandmarks.get(i).getBoundingBox(), outputWidth, outputHeight);    // updated
//          Rect r = faceLandmarks.get(i).getBoundingBox(); // original
                        canvas.drawRect(r, circlePaint);
                        canvas.drawBitmap(testFaceBitmaps.get(i), r.left, r.top, circlePaint);
            }
        }
 }


protected void processImage(byte[] data, int previewWidth, int previewHeight, int outputWidth, int outputHeight) {

.......
......
    if(testBitmap != null){
        testBitmap.recycle();
    }
    testBitmap = Face.Image.convertCameraYUVData(
            data,
            previewWidth, previewHeight,
            outputWidth, outputHeight,
//          - 90,     // original
//          true);    // original
            0,          // updated
            false);     // updated


    
    Rect tmpRect = new Rect(0,1,0,1);  // added,临时变量,可不要。
    
    if(testBitmap != null && faceDetect.getFaceCount() > 0){
        if(faceLandmarks != null){
            for (int i = 0; i < faceLandmarks.size(); i++) {
                tmpRect = Transform_anticlock_90deg(faceLandmarks.get(i).getBoundingBox(),outputWidth,outputHeight); //added
                    Bitmap face = BitmapUtils.getDstArea(testBitmap, tmpRect); //added
//               Bitmap face = BitmapUtils.getDstArea(testBitmap, faceLandmarks.get(i).getBoundingBox());
                 face = BitmapUtils.blurByGauss(face, 50);
                 testFaceBitmaps.add(face);
            }
        }
    }
......
......
}


// 以下为新增代码。坐标原点(0,0)在左上角,显示区域在第四象限
    public Rect Transform_anticlock_90deg(Rect inRect, int view_width, int view_height)  // 逆时针转90°并水平镜像
    {
        Rect outRect = new Rect(0,10,0,10);
        final float h_to_w_ratio = (float)view_height/(float)view_width;
        final int x0,y0,x1,y1,newX0,newY0,newX1,newY1;
        x0 = inRect.left;    // 实际不需要x0
        y0 = inRect.top;
        x1 = inRect.left + inRect.width();
        y1 = inRect.top + inRect.height();

        //计算逆时针转90°后的坐标(含宽高比转换)
        newX0 = (int)((float)y0 / h_to_w_ratio);
        newY0 = (int)((float)(view_width - x1) * h_to_w_ratio);
        newX1 = (int)((float)y1 / h_to_w_ratio);
        newY1 = (int)((float)inRect.width() * h_to_w_ratio) + newY0;
        //生成旋转后的Rect
        outRect.set(newX0,newY0,newX1,newY1);
        //水平镜像
        outRect.set(RectMirror(outRect,view_width,view_height,true));
        
        return outRect;
    }

    private Rect RectMirror(Rect inRect, int view_width, int view_height, boolean isHorizontal)    // 镜像方法
    {
        Rect outRect = new Rect();
        
        if (isHorizontal == true) {    //水平镜像
            outRect.set(view_width - inRect.right, inRect.top, view_width - inRect.left, inRect.bottom);
        }
        else {                        //垂直镜像
            outRect.set(inRect.left, view_height-inRect.bottom, inRect.right, view_height-inRect.top);
        }
        return outRect;
    }
  • 另外修改显示的画面大小的地方也在ClassfierActivity.java里
protected Size getDesiredPreviewFrameSize() {
        return new Size(1920, 1080);  //我的片源是1080p的,如果改小了好像会显示不全,还是对Camera玩得不熟。
    }
  • 旋转以后的图像就正确了:

 

Tengine-Kit的github源码 TengineKit.Image类封装了一系列工具API,帮助开发者快速方便的处理图片相关的功能,具体功能请查阅文档,这里我们将用这个TengineKit.Image里面的API实现Android前置摄像头视频流转为Bitmap(YUV_NV21转RGBA)。 立即下载

相关推荐

TengineKit:TengineKit-免费,快速,轻松,实时的移动设备上的面部检测和面部地标,面部属性,手部检测,手部地标,身体检测,身体地标和虹膜地标SDK

TengineKit,由OPEN AI LAB开发。 TengineKit是一个易于集成的AI算法SDK。 目前,它可以以非常低的延迟在各种手机上运行。 我们将继续更新该项目,以获得更好的结果和更好的性能! 影响 人脸检测和脸部2d标志 脸部3d地标& 虹膜 上身检测与上体标志性建筑 手部检测与手地标 Gif 主持人之舞 影片( | ) 试试 可以直接下载并将其安装在手机上以查看效果。 要么 扫描代码下载apk 目标 在移动客户端中提供最佳性能 在移动客户端中提供最简单的API 提供移动客户端中最小的程序包 特征 人脸检测 面对地标 面对3dlandmarks 面部属性,例如:年龄,性别,微笑,眼镜 眼虹膜和地标 手动检测(实时,尚未在移动设备上) 手动地标(实时,尚未在移动设备上) 身体检测(实时,尚未在移动设备上) 身体滑行(实时,尚未在移动设备上) 更新(2021/01/08) Khadas NPU应用 提高了人脸检测和人脸标志的速度 更新资料夹 更新Linux模型 更新Core v0.0.2和Face v0.0.2 性能(人脸检测和人脸标志)(减少时间)

Tengine-Kit人脸检测及关键点

Tengine-Kit 人脸检测及关键点 Tengine-Kit是一个在Android上的一个算法集合。目前的算法有,人脸检测及关键点,虹膜关键点,身体检测及关键点,手的检测及关键点。 Tengine-Kit地址 1.build.gradle引入库 implementation 'com.tengine.tenginekit:core:0.0.1' implementation 'com.tengine.tenginekit:face:0.0.1' 2.得到图像的byte数据 Bitmap bb = nu

qq_21370465的博客 2313

VS2103+Intel2013+MSMPI运行Fortran并行程序

VS2103+Intel2013+MSMPI运行Fortran并行程序MSMPI安装新建Fortran90项目编写Fortran并行程序在cmd运行编译完成的执行文件 MSMPI安装 我这里采用的是Microsoft MPI v9.0.1,可以点此下载。下载完成后同时安装msmpisdk.msi、msmpisetup.exe两个文件,安装位置默认即可。 其中msmpisdk.msi的默认安装路径在C:\Program Files (x86)\Microsoft SDKs\MPI,该文件包含了mpi环境所需

weixin_43176703的博客 2936

TengineKit:一款强大的移动端AI算法SDK

TengineKit是一款由OPEN AI LAB开发的易于集成的AI算法SDK,主要使用C++、C、Kotlin和Java等编程语言。该项目能够在移动设备上实现低延迟的运行,为开发者提供高效的人工智能功能。 ## 核心功能 - **人脸检测**:实时检测移动设备相机捕获的图像中的人脸。 - **人脸标志点**:包括2D和3D的人脸标志点定位,用于精确描绘人脸特征。 - **人脸属性识别**:...

gitblog_01171的博客 409

扣子(coze)案例^第22期:零代码打造小红书竞品监控系统+AI自动生成运营策略建议

本文详细介绍了如何利用扣子(coze)平台零代码搭建小红书竞品监控系统。该系统通过自动化工作流抓取竞品笔记数据,并存入飞书多维表格,结合AI能力自动生成包含可视化分析报告在内的运营策略建议,帮助运营者高效进行数据驱动的市场分析。

weixin_29313239的博客 1004

stackelberg博弈_博弈论、多智能体、强化学习(随便记点东西)

多智能体应用场景:已实现:游戏AI。正在努力:UAV,物资运输,快递分发,交通系统。未来:社会学,预测群体行为,城市区域合作,国际关系。博弈论基本定义:玩家集合: 策略集合: 收益函数: 囚徒困境:两智能体矩阵博弈坦白抵赖坦白1,13,0抵赖0,32,2占优策略与最佳应对:上表中两者均具有占优策略,即无论如何都应该选坦白。那么构造下表。坦白抵赖坦白1,13,0抵赖0,12,2对于玩家一来说,坦白...

weixin_39611722的博客 2997

rk3399性能_在 RK3399 上部署 Tengine AI 框架

Tengine on rk3399TengineTengine 是 OPEN AI LAB 一款轻量级神经网络推理引擎,它针对 Arm 嵌入式平台进行了专门优化,对 Android、Linux 系统都提供了很好的支持。而且更加难能可贵的是 Tengine 并不依赖于专用 AI 芯片(即 Tengine 可以利用 GPU、NPU 这些具有专门 AI 加速功能的模块进行 AI 运算,也可以利用通用的 ...

weixin_39774044的博客 519

AB SCIEX质谱数据分析实战:从PeakView入门到精通

质谱分析是现代生命科学和药物研发中不可或缺的核心技术,它通过测量离子的质荷比来鉴定和定量化合物。其基本原理是将样品离子化后,在电场和磁场中按质荷比分离,最终形成质谱图。这项技术的核心价值在于能够从复杂混合物中高灵敏度、高特异性地获取化合物的定性和定量信息,广泛应用于代谢组学、蛋白质组学、环境监测和药物分析等领域。在实际工作中,高效的数据处理平台至关重要。以AB SCIEX质谱仪生成的.wiff文件为例,其原始数据需要专业软件进行解析。PeakView软件正是这样一个综合平台,它集成了高级数据处理、谱图解析和

weixin_29053577的博客 306

在rk3399上配置Tengine AI框架

参考链接: 在 RK3399 开发板上部署 Tengine AI 框架. 下载源码 从https://github.com/OAID/tengine/下载源码 git clone --recurse-submodules https://github.com/OAID/tengine/ 注:一定要加 --recurse-submodules 不然可能源码下载不全 安装依赖 sudo ap...

BISTU_theRookie的博客 1891

LEC/FORMAL --- PARTIII debug

lec(logic equivalence checking)又叫formal check,是对ic design的综合,PR前后的设计进行逻辑对比检查的工具/手段,保证综合不改变rtl原始的logic function。目前用的较多的就是C家的formal工具。接下来介绍一下lec过程中遇到的问题以及debug手段。...

sinat_27691203的博客 7706

HighTec安装使用

HighTec安装使用

qq_43552564的博客 3833

rk3399性能_在 RK3399 开发板上部署 Tengine AI 框架

TengineTengine 是 OPEN AI LAB 一款轻量级神经网络推理引擎,它针对 Arm 嵌入式平台进行了专门优化,对 Android、Linux 系统都提供了很好的支持。而且更加难能可贵的是 Tengine 并不依赖于专用 AI 芯片(即 Tengine 可以利用 GPU、NPU 这些具有专门 AI 加速功能的模块进行 AI 运算,也可以利用通用的 CPU 进行 AI 运算...

weixin_39608394的博客 407

UG NX二次开发(C#)-读取PMI对象的名称

摘要:本文介绍了在UG NX中通过NXOpen获取PMI对象名称的方法。首先说明PMI对象初始无名称,可通过重命名或属性设置名称。然后提供C#代码示例,展示如何遍历PMI集合获取对象名称,并显示名称和类型信息。适用于需要操作PMI对象的开发人员,欢迎加入技术交流QQ群749492565。(99字)

GimiGimmy 590

tengine mysql_在 RK3399 上部署 Tengine AI 框架

Tengine on rk3399TengineTengine 是 OPEN AI LAB 一款轻量级神经网络推理引擎,它针对 Arm 嵌入式平台进行了专门优化,对 Android、Linux 系统都提供了很好的支持。而且更加难能可贵的是 Tengine 并不依赖于专用 AI 芯片(即 Tengine 可以利用 GPU、NPU 这些具有专门 AI 加速功能的模块进行 AI 运算,也可以利用通用的 ...

weixin_30444573的博客 302

基于YOLOv11的水果/商品/食堂/蔬菜/饮料/书籍识别与计价系统,前台+后台管理系统

基于YOLOv11的水果/商品/食堂/蔬菜/饮料/书籍识别与计价系统,前台+后台管理系统

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1218

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

ARM版 rk3399 编译opencv+tengine 以及usb相机无法识别问题解决

1.下载opencv 链接:https://pan.baidu.com/s/1K3ngUnBpae3kn9TxDcXihQ 提取码:96qs 复制这段内容后打开百度网盘手机App,操作更方便哦 2.解压 unzip opencv* 3.安装依赖项 apt-get update apt-get upgrade #可能需要较长的时间,耐心等待 apt-get install build-essential apt-get install pkg-config ap...

xuguosheng1992的博客 1433

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

rk3399pro上安装rknnplugin的各模型测试

# DIY operators rknnplugin 环境:RK3399pro + fedora [![GitHub license](http://OAID.github.io/pics/apache_2.0.svg)](./LICENSE) 1. 下载Tengine [Tengine in GitHub](git@192.168.234.8:8022/internal/tengin...

非学无以广才 非志无以成学 1089

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

3399引擎_韦东山-在 RK3399 上部署 Tengine AI 框架 - 百问网嵌入式问答社区

[md]# Tengine on rk3399## TengineTengine 是 OPEN AI LAB 一款轻量级神经网络推理引擎,它针对 Arm 嵌入式平台进行了专门优化,对 Android、Linux 系统都提供了很好的支持。而且更加难能可贵的是 Tengine 并不依赖于专用 AI 芯片(即 Tengine 可以利用 GPU、NPU 这些具有专门 AI 加速功能的模块进行 AI 运算,...

weixin_42311301的博客 521

使用Tengine Explore版在firefly-RK3399上实现实时目标检测

使用深度学习的方法训练得到模型之后,下一步便是将模型部署到实际的应用场景中创造效益,通常就是部署到服务器端,或者部署到移动端,我们做的是后者。 近些年来,用于将模型部署到移动端的前向推理框架比较多,例如ncnn、MACE、Tengine等,当然如果有条件,还是需要自己来做优化。 Tengine是一个由OPEN AI LAB开发的专门针对嵌入式场景的轻量化框架,我们对比了ncnn、MACE和Teng...

u013533037的博客 2151

tengine简单安装_即使没有强大的NPU、GPU,AI门外汉也能开发AI应用-边缘AI推理框架Tengine...

本文转自 HackforFun 原标题:「在 RK3399 开发板上部署 Tengine AI 框架」TengineTengine 是 OPEN AI LAB 一款轻量级神经网络推理引擎,它针对 Arm 嵌入式平台进行了专门优化,对 Android、Linux 系统都提供了很好的支持。而且更加难能可贵的是 Tengine 并不依赖于专用 AI 芯片(即 Tengine 可以利用 GPU、NPU 这...

weixin_31925495的博客 508

Tengine-Lite 、Tengine安装-使用

https://tengine-docs.readthedocs.io/zh_CN/latest/source_compile/compile_linux.html https://blog.csdn.net/weixin_40920183/article/details/107373945 https://github.com/OAID/Tengine Tengine支持GPU / CPU异构调度丨OPEN AI LAB 在rk3399(rockpi 4b)上部署Tengine AI框架(CPU)测试(l

weixin_41642203的博客 2106

使用Tengine Explore版在firefly-RK3399上开发多线程项目

这是Tengine Explore版本系列文章的第二篇。 上一篇,我们讲到,使用Tengine Explore版本在firefly-RK3399上实现了实时目标检测的一个demo,并且对比了开源版,Explore版(float32),Explore版(int8)三者的性能。本篇,我们将在此基础上充分挖掘Tengine Explore和firefly-RK3399的强大性能。 Tengine不仅支持...

u013533037的博客 1531

C语言应用到SSD,0#01 解析mobile_ssd样例代码

1.预备知识2.样例程序介绍3.运行代码3.1.能在笔记本上成功运行 mobilenet_ssd 样例代码。3.2.理解 Tengine 的工作方式。3.3.能在 RK3399 上运行该程序。3.4.能在 RK3399 上运行该程序并使用 GPU 加速1.预备知识CLion:一款优秀的C语言开发工具。主要是有免费的社区版本,并且能支持cmake文件的编译。最大的福利就是支持Ubuntu安装。环境安...

weixin_30949015的博客 527

EAIDK-610 fedora系统上搭建Tengine环境

EAIDK-610 fedora系统上搭建Tengine环境 一、 在EAIDK-610安装fedora系统 首先需要一个typec,EAIDK,电源线,以及镜像文件和安装软件(镜像文件和安装软件https://pan.baidu.com/s/1ztI7Y9f26PliimNF1RNXjg 提取码:ehwt) (1 )software > FlashTool>EAIDK_Flash...

weixin_44302627的博客 1564

rk3399性能_瑞芯微RK3399通过人工智能产业发展联盟(AIIA)首轮AI芯片评估-Tengine...

3月6日,由国际电信联盟、中国信息通信研究院联合主办,人工智能产业发展联盟(AIIA)和中兴通讯承办的国际论坛“AI in 5G——引领新时代论坛”在深圳召开。会上,AIIA正式发布“AIIA DNN benchmark V0.5”首轮评估结果,瑞芯微Rockchip RK3399作为首轮评估产品通过评测。AIIA DNN benchmark V0.5测试评估主要面向端侧,基于AIIA权威测试平台...

weixin_39677203的博客 174
上一篇: 【转载】如何从源码编译OpenCV4Android库
下一篇: 【转载】CMake 语法 - 详解 CMakeLists.txt
LateLinux
博客等级 码龄18年 65粉丝 25原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值