用39块钱的全志V851se视觉开发板做了个小相机,还可以物品识别、自动追焦!

news/2024/4/19 16:26:40/

用39块钱的V851se视觉开发板做了个小相机。

在这里插入图片描述

可以进行物品识别、自动追焦!

在这里插入图片描述

在这里插入图片描述

这个超低成本的小相机是在V851se上移植使用全志在线开源版本的Tina Linux与OpenCV框架开启摄像头拍照捕获视频,并结合NPU实现Mobilenet v2目标分类识别以及运动追踪等功能…并最终实现功能完整的智能小相机。

ISP适配

可以适配V851se的Tina5.0升级到了21.05版本的OpenWrt,相较于商业量产版本的Tina Linux 支持更多新的软件包,不过可惜的是MPP包没有移植到Tina5.0,所以想使用摄像头就需要另辟蹊径。

虽然Tina5.0并没有移植MPP包,但也内置了一个libAWispApi包,支持在用户层对接 ISP,但是很可惜这个包也没有适配V85x系列,这里就需要自行适配。

其实适配很简单,SDK 已经提供了lib只是没提供编译支持,我们需要前往以下文件夹中新建一个v851se文件夹:

openwrt/package/allwinner/vision/libAWIspApi/machinfo

然后再新建文件build.mk写入如下配置:

ISP_DIR:=isp600

在这里插入图片描述

然后在menuconfig中勾选上这个包,并进行如下配置:

Allwinner  --->Vision  ---><*> camerademo........................................ camerademo test sensor  --->[*]   Enabel vin isp support

在这里插入图片描述

编译系统然后烧录系统,运行命令 camerademo ,可以看到是正常拍摄照片的

在这里插入图片描述

OpenCV适配

OpenCV在打包好的固件中已经默认适配好了,如果不想了解如何适配OpenCV可以直接前往点击链接获取资料并跳过这部分

OpenCV默认不支持开启RAW Sensor,不过现在需要配置为OpenCV开启RAW Sensor抓图,然后通过OpenCV送图到之前适配的libAWispApi库进行 ISP 处理。

在这里增加一个函数作为 RAW Sensor 抓图的处理。

#ifdef __USE_VIN_ISP__
bool CvCaptureCAM_V4L::RAWSensor()
{struct v4l2_control ctrl;struct v4l2_queryctrl qc_ctrl;memset(&ctrl, 0, sizeof(struct v4l2_control));memset(&qc_ctrl, 0, sizeof(struct v4l2_queryctrl));ctrl.id = V4L2_CID_SENSOR_TYPE;qc_ctrl.id = V4L2_CID_SENSOR_TYPE;if (-1 == ioctl (deviceHandle, VIDIOC_QUERYCTRL, &qc_ctrl)){fprintf(stderr, "V4L2: %s QUERY V4L2_CID_SENSOR_TYPE failed\n", deviceName.c_str());return false;}if (-1 == ioctl(deviceHandle, VIDIOC_G_CTRL, &ctrl)) {fprintf(stderr, "V4L2: %s G_CTRL V4L2_CID_SENSOR_TYPE failed\n", deviceName.c_str());return false;}return ctrl.value == V4L2_SENSOR_TYPE_RAW;
}
#endif

这段代码的功能是检查V4L2摄像头设备的传感器类型是否为RAW格式。它使用了V4L2的ioctl函数来查询和获取传感器类型信息。

然后在OpenCV的捕获流函数:

bool CvCaptureCAM_V4L::streaming(bool startStream)

添加 ISP 处理

#ifdef __USE_VIN_ISP__RawSensor = RAWSensor();if (startStream && RawSensor) {int VideoIndex = -1;sscanf(deviceName.c_str(), "/dev/video%d", &VideoIndex);IspPort = CreateAWIspApi();IspId = -1;IspId = IspPort->ispGetIspId(VideoIndex);if (IspId >= 0)IspPort->ispStart(IspId);} else if (RawSensor && IspId >= 0 && IspPort) {IspPort->ispStop(IspId);DestroyAWIspApi(IspPort);IspPort = NULL;IspId = -1;}
#endif

这段代码主要用于控制图像信号处理(ISP)的启动和停止。根据条件的不同,可以选择在开始视频流捕获时启动ISP流处理,或者在停止视频流捕获时停止ISP流处理,以便对视频数据进行处理和增强。

至于其他包括编译脚本的修改,全局变量定义等操作,可以参考原文链接中的补丁文件。

在执行完以上步骤后,可以快速测试摄像头输出demo:

OpenCV  ---><*> opencv....................................................... opencv libs[*]   Enabel sunxi vin isp support<*> opencv_camera.............................opencv_camera and display image

在这里插入图片描述

MobileNet V2

MobileNet V2是一种轻量级的卷积神经网络,它专为移动设备和嵌入式设备上的实时图像分类和目标检测任务设计。

MobileNet V2的关键特点包括使用深度可分离卷积来减少计算量和参数数量,引入带线性瓶颈的倒残差结构以增加非线性表示能力,以及提供宽度乘数参数以适应不同计算资源限制。这些特点使得MobileNet V2成为资源受限的移动设备上的理想选择。

首先对输入图像进行预处理,以适应MobileNet V2 SSD模型的输入要求。通过通道格式转换、图像大小调整和数据填充等操作,将输入图像转换为适合模型输入的格式。

void get_input_data(const cv::Mat& sample, uint8_t* input_data, int input_h, int input_w, const float* mean, const float* scale){cv::Mat img;if (sample.channels() == 1)cv::cvtColor(sample, img, cv::COLOR_GRAY2RGB);elsecv::cvtColor(sample, img, cv::COLOR_BGR2RGB);cv::resize(img, img, cv::Size(input_h, input_w));uint8_t* img_data = img.data;/* nhwc to nchw */for (int h = 0; h < input_h; h++) {for (int w = 0; w < input_w; w++) {for (int c = 0; c < 3; c++) {int in_index = h * input_w * 3 + w * 3 + c;int out_index = c * input_h * input_w + h * input_w + w;input_data[out_index] = (uint8_t)(img_data[in_index]);  //uint8

关键步骤是要实现非极大值抑制算法(NMS),用于去除高度重叠的框,只保留得分最高的那个框。算法通过计算框之间的交集面积和设置的阈值来进行筛选,并将保留的框的索引存储在picked向量中。

// 非极大值抑制算法(NMS)
static void nms_sorted_bboxes(const std::vector<Bbox_t>& bboxs, std::vector<int>& picked, float nms_threshold) {picked.clear();const int n = bboxs.size();// 创建存储每个框面积的向量std::vector<float> areas(n);// 计算每个框的面积并存储for (int i = 0; i < n; i++){areas[i] = (bboxs[i].xmax - bboxs[i].xmin) * (bboxs[i].ymax - bboxs[i].ymin);

通过一系列操作,包括转换为向量、计算缩放比例、创建存储检测结果的向量等,将输出数据转换为检测结果,并按照置信度从高到低排序。然后应用非极大值抑制算法对检测结果进行筛选,最后将筛选后的目标框位置、大小和类别置信度等信息绘制在图像上。

// 按照分数对框进行排序std::sort(BBox.begin(), BBox.end(), comp);// 应用非极大值抑制算法,获取保留的框的索引std::vector<int> keep_index;nms_sorted_bboxes(BBox, keep_index, iou_threshold);// 创建存储框位置的向量std::vector<cv::Rect> bbox_per_frame;// 遍历保留的框,绘制框和标签for(int i = 0; i < keep_index.size(); i++) {int left = BBox[keep_index[i]].xmin;int top = BBox[keep_index[i]].ymin;int right = BBox[keep_index[i]].xmax;int bottom = BBox[keep_index[i]].ymax;cv::rectangle(bgr, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(0, 0, 255), 1);char text[256];sprintf(text, "%s %.1f%%", class_names[BBox[keep_index[i]].cls_idx], BBox[keep_index[i]].score * 100);cv::putText(bgr, text, cv::Point(left, top), cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 255, 255), 1, 8, 0);bbox_per_frame.emplace_back(left, top, width, height);}

在这里插入图片描述

NPU开发流程

V851se芯片内置一颗NPU,其处理性能为最大0.5TOPS并有128KB内部高速缓存用于高速数据交换,NPU 开发完整的流程如下图所示:

在这里插入图片描述

模型训练

在模型训练阶段,用户根据需求和实际情况选择合适的框架(如Caffe、TensorFlow 等)使用数据集进行训练得到符合需求的模型,此模型可称为预训练模型。也可直接使用已经训练好的模型。V851s 的 NPU 支持包括分类、检测、跟踪、人脸、姿态估计、分割、深度、语音、像素处理等各个场景90 多个公开模型。

signal函数

在模型转化阶段,通过Acuity Toolkit把预训练模型和少量训练数据转换为NPU可用的模型NBG文件。一般步骤如下:

1、模型导入,生成网络结构文件、网络权重文件、输入描述文件和输出描述文件。
2、模型量化,生成量化描述文件和熵值文件,可改用不同的量化方式。
3、仿真推理,可逐一对比float和其他量化精度的仿真结果的相似度,评估量化后的精度是否满足要求。
4、模型导出,生成端侧代码和*.nb 文件,可编辑输出描述文件的配置,配置是否添加后处理节点等。

在这里插入图片描述


http://www.ppmy.cn/news/1364184.html

相关文章

Github 2024-02-23 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-02-23统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量非开发语言项目4Python项目3TypeScript项目1HTML项目1Dart项目1Rust项目1 从零开始构建你喜爱的技术 创建周…

2月26日做题总结(C/C++真题)

今天是2024年2月16日&#xff0c;新学期开学第一天。在大三这个重要阶段&#xff0c;我决定参加24年秋招。在准备项目的同时&#xff0c;也先做一些入门的笔试题吧&#xff0c;慢慢积累。如果你也是处于这个阶段&#xff0c;欢迎来找我交流讨论&#xff01; 今天是做题第一天&a…

SQL注入漏洞解析-less-8(布尔盲注)

我们来看一下第八关 当我们进行尝试时&#xff0c;他只有You are in...........或者没有显示。 他只有对和错显示&#xff0c;那我们只能用对或者错误来猜他这个数据库 ?id1%27%20and%20ascii(substr(database(),1,1))>114-- ?id1%27%20and%20ascii(substr(database(),1,…

SQL注入漏洞解析--less-46

我们先看一下46关 他说让我们先输入一个数字作为sort,那我们就先输入数字看一下 当我们分别输入1&#xff0c;2&#xff0c;3可以看到按照字母顺序进行了排序&#xff0c;所以它便是一个使用了order by语句进行排序的查询的一种查询输出方式 当输入时出现报错提示&#xff0c;说…

css transform 会影响position 定位

比如通过以下代码.实现导航条上的每个li栏目,以不同的时间间隔,从上向下移动进来并显示 .my-navbar ul li {position: relative;opacity: 0;transform: translateY(-30px);transition: transform .6s cubic-bezier(.165,.84,.44,1),opacity .6s cubic-bezier(.165,.84,.44,1);…

JWT学习笔记

了解 JWT Token 释义及使用 | Authing 文档 JSON Web Token Introduction - jwt.io JSON Web Token (JWT&#xff0c;RFC 7519 (opens new window))&#xff0c;是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准&#xff08;(RFC 7519)。该 token 被设计为紧凑…

python爬虫实战:获取电子邮件和联系人信息

引言 在数字时代&#xff0c;电子邮件和联系人信息成为了许多企业和个人重要的资源&#xff0c;在本文中&#xff0c;我们将探讨如何使用Python爬虫从网页中提取电子邮件和联系人信息&#xff0c;并附上示例代码。 目录 引言 二、准备工作 你可以使用以下命令来安装这些库&a…

批量获取图片(上)

1.文件的路径 在Windows系统的路径中&#xff0c;我们使用反斜线 ( \ ) 分隔各个文件夹和文件名。 而在macOS系统中&#xff0c;文件夹和文件名使用正斜线 ( / ) 进行分隔。 2.打开文件 在Python语言中&#xff0c;open()函数表示要打开一个文件&#xff0c;对文件进行处理的…

【pytorch】常用代码

文章目录 条件与概率torch.tensor()torch.rand()torch.randn()torch.randint()torch.multinominal() 逻辑运算torch.argmax()torch.max()torch.sum()torch.tanh()torch.pow() 功能性操作 torch.nn.functionalF.normalize()F.elu()F.relu()F.softmax() 张量计算torch.zeros()tor…

移动端rem适配

如果需要使用 rem 单位&#xff0c;推荐使用以下两个工具&#xff1a; postcss-pxtorem 是一款 postcss 插件&#xff0c;用于将单位转化为 rem lib-flexible 用于设置 rem 基准值 下面我们分别将这两个工具配置到项目中完成 REM 适配。 一、使用 lib-flexible 动态设置 RE…

YOLOv9尝鲜测试五分钟极简配置

pip安装python包&#xff1a; pip install yolov9pip在https://github.com/WongKinYiu/yolov9/tree/main中下载好权重文件yolov9-c.pt。 运行下面代码&#xff1a; import yolov9model yolov9.load("yolov9-c.pt", device"cpu") # load pretrained or c…

Linux 学习笔记(4)

四、 文件权限 1 、文件类型 Linux 广泛的被很多用户所接受&#xff0c;它强大的功能受到很多人喜欢&#xff0c; Linux 文件一般是用一些相关的应 用程序创建&#xff0c;比如图像工具、文档工具、归档工具 ... .... 或 cp 工具等。 Linux 文件的删除方式是用 rm 命…

【Android】坐标系

Android 系统中有两种坐标系&#xff0c;分别为 Android 坐标系和 View 坐标系。了解这两种坐标系能够帮助我们实现 View 的各种操作&#xff0c;比如我们要实现 View 的滑动&#xff0c;你连这个 View 的位置都不知道&#xff0c;那如何去操作呢&#xff1f; 一、Android 坐标…

LeetCode第七题: 整数反转

题目描述 给你一个 32 位的有符号整数 x​ &#xff0c;返回将 x​ 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1]​ &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 示例 …

自动驾驶---行业发展及就业环境杂谈

进入21世纪以来&#xff0c;自动驾驶行业有着飞速的发展&#xff0c;自动驾驶技术&#xff08;L2---L3&#xff09;也逐渐落地量产到寻常百姓家。虽然最早期量产FSD的特斯拉有着深厚的技术积累&#xff0c;但是进入2010年以后&#xff0c;国内的公司也逐渐发展起来自己的自动驾…

unity-unity2d基础操作笔记(二)0.5.101

unity2d基础操作笔记 五十一、canvas中的必须熟悉的属性五十二、如何调整canvas与游戏人物大小近似大小五十三、canvas中的canvas scaler介绍【概念】五十四、ui scale mode介绍【概念】五十五、为什么创建image后,canvas的范围要要远远大于游戏世界?五十六、图片常用操作【技…

将SU模型导入ARCGIS,并获取高度信息,多面体转SHP文件(ARCMAP)

问题:将Sketchup中导出的su模型,导入arcgis并得到面shp文件,进而获取各建筑的高度、面积等信息。 思路: (1)导入arcgis得到多面体 (2)转为面shp文件 (3)计算高度/面积等 1、【3D Analyst工具】【转换】【由文件转出】【导入3D文件】(在此步骤之间,建议先建立一个…

安全生产:AI视频智能分析网关V4如何应用在企业安全生产场景中?

随着科技的不断进步&#xff0c;视频智能分析技术在安全生产领域中的应用越来越广泛。这种技术通过计算机视觉和人工智能算法&#xff0c;可以对监控视频进行自动分析和处理&#xff0c;以实现多种功能&#xff0c;如目标检测、行为识别、异常预警等。今天我们以TSINGSEE青犀AI…

LASSO算法

LASSO (Least Absolute Shrinkage and Selection Operator) 是一种回归分析的方法&#xff0c;它能够同时进行变量选择和正则化&#xff0c;以增强预测准确性和模型的解释性。LASSO通过在损失函数中加入一个L1惩罚项来实现这一点。该惩罚项对系数的绝对值进行约束。 基本概念 …

019 Spring Boot+Vue 电影院会员管理系统(源代码+数据库+文档)

部分代码地址&#xff1a; https://github.com/XinChennn/xc019-cinema 一、系统介绍 cinema项目是一套电影院会员管理系统&#xff0c;使用前后端分离架构开发包含管理员、会员管理、会员卡管理、电影票、消费记录、数据统计等模块 二、所用技术 后端技术栈&#xff1a; …