基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统(可修改为coco 80类目标检测)

●项目名称
基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统(可修改为coco 80类目标检测)

●项目简介

本项目在Aidlux上部署鸟类检测驱赶系统,通过视觉技术检测到有鸟类时,会进行提示。并可在源码上修改coco 80类目标检测索引直接检测其他79类目标,可以直接修改、快速移植到自己的项目中。

●预期效果

本项目使用利用安装AidLux的AidLux设备s855实现,可以让任何AidLux使用者快速上手,体验深度学习检测效果,提高开发乐趣。

边缘计算设备的优势主要包括以下几个方面:
节省带宽:边缘计算设备可以在源头处理数据,只传输重要的数据,从而节省带宽。
减少延迟:边缘计算设备可以减少等待时间,提高响应速度。
优化网络性能:边缘计算设备可以帮助企业实时分析和处理数据,从而提高网络性能。
提供本地化服务:边缘计算设备可以提供本地化服务,例如在智能城市、自动驾驶汽车和医疗保健行业中,边缘计算设备可以提供更快速、更准确的服务。
提高安全性:边缘计算设备可以减少数据传输过程中的安全风险,提高安全性。

对于大多数企业来说,coco的80类可支持大部分场景的预研、模拟,本项目将yolov5移植至AidLux,可在源码中直接修改类别,实现80类中任何一类的检测。

对于开发者而言,AI项目中各种算法的数据集准备+模型训练+模型部署依然存在着不小的难度。AidLux的出现,可以将我们的安卓设备以非虚拟的形式变成同时拥有Android和Linux系统环境的边缘计算设备,支持主流AI框架,非常易于部署,还有专门的接口调度算力资源,极大地降低了AI应用落地门槛。

Aidlux简介

Aidlux基于ARM架构的跨生态(Android/鸿蒙+Linux)一站式AIoT应用开发和部署平台
在这里插入图片描述
可在安卓手机(软硬件最低配置要求:①Android 系统版本 >= 6,②剩余存储空间 > 650MB (AidLux1.1),③CPU 支持 arm64-v8a 架构)

和其发布的边缘计算设备上运行、开发

下面上源码:
这里用opencv进行视频。我们检测鸟类图片,在coco 80类目标检测中索引为14(从0开始),所以设置sign=14,。如果是行人或者其他,直接修改sign的值为对应索引即可。

相关后处理函数utils.py

import cv2
import numpy as npcoco_class = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light','fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow','elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee','skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard','tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple','sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch','potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone','microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear','hair drier', 'toothbrush']def xywh2xyxy(x):'''Box (center x, center y, width, height) to (x1, y1, x2, y2)'''y = np.copy(x)y[:, 0] = x[:, 0] - x[:, 2] / 2  # top left xy[:, 1] = x[:, 1] - x[:, 3] / 2  # top left yy[:, 2] = x[:, 0] + x[:, 2] / 2  # bottom right xy[:, 3] = x[:, 1] + x[:, 3] / 2  # bottom right yreturn ydef xyxy2xywh(box):'''Box (left_top x, left_top y, right_bottom x, right_bottom y) to (left_top x, left_top y, width, height)'''box[:, 2:] = box[:, 2:] - box[:, :2]return boxdef NMS(dets, thresh):'''单类NMS算法dets.shape = (N, 5), (left_top x, left_top y, right_bottom x, right_bottom y, Scores)'''x1 = dets[:,0]y1 = dets[:,1]x2 = dets[:,2]y2 = dets[:,3]areas = (y2-y1+1) * (x2-x1+1)scores = dets[:,4]keep = []index = scores.argsort()[::-1]while index.size >0:i = index[0]       # every time the first is the biggst, and add it directlykeep.append(i)x11 = np.maximum(x1[i], x1[index[1:]])    # calculate the points of overlap y11 = np.maximum(y1[i], y1[index[1:]])x22 = np.minimum(x2[i], x2[index[1:]])y22 = np.minimum(y2[i], y2[index[1:]])w = np.maximum(0, x22-x11+1)    # the weights of overlaph = np.maximum(0, y22-y11+1)    # the height of overlapoverlaps = w*hious = overlaps / (areas[i]+areas[index[1:]] - overlaps)idx = np.where(ious<=thresh)[0]index = index[idx+1]   # because index start from 1return dets[keep]def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True, stride=32):# Resize and pad image while meeting stride-multiple constraintsshape = img.shape[:2]  # current shape [height, width]if isinstance(new_shape, int):new_shape = (new_shape, new_shape)# Scale ratio (new / old)r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])if not scaleup:  # only scale down, do not scale up (for better test mAP)r = min(r, 1.0)# Compute paddingratio = r, r  # width, height ratiosnew_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh paddingif auto:  # minimum rectangledw, dh = np.mod(dw, stride), np.mod(dh, stride)  # wh paddingelif scaleFill:  # stretchdw, dh = 0.0, 0.0new_unpad = (new_shape[1], new_shape[0])ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratiosdw /= 2  # divide padding into 2 sidesdh /= 2if shape[::-1] != new_unpad:  # resizeimg = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))left, right = int(round(dw - 0.1)), int(round(dw + 0.1))img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add borderreturn img, ratio, (dw, dh)def preprocess_img(img, target_shape:tuple=None, div_num=255, means:list=[0.485, 0.456, 0.406], stds:list=[0.229, 0.224, 0.225]):'''图像预处理:target_shape: 目标shapediv_num: 归一化除数means: len(means)==图像通道数,通道均值, None不进行zscorestds: len(stds)==图像通道数,通道方差, None不进行zscore'''img_processed = np.copy(img)# resizeif target_shape:# img_processed = cv2.resize(img_processed, target_shape)img_processed = letterbox(img_processed, target_shape, stride=None, auto=False)[0]img_processed = img_processed.astype(np.float32)img_processed = img_processed/div_num# z-scoreif means is not None and stds is not None:means = np.array(means).reshape(1, 1, -1)stds = np.array(stds).reshape(1, 1, -1)img_processed = (img_processed-means)/stds# unsqueezeimg_processed = img_processed[None, :]return img_processed.astype(np.float32)def convert_shape(shapes:tuple or list, int8=False):'''转化为aidlite需要的格式'''if isinstance(shapes, tuple):shapes = [shapes]out = []for shape in shapes:nums = 1 if int8 else 4for n in shape:nums *= nout.append(nums)return outdef scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):# Rescale coords (xyxy) from img1_shape to img0_shapeif ratio_pad is None:  # calculate from img0_shapegain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])  # gain  = old / newpad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2  # wh paddingelse:gain = ratio_pad[0][0]pad = ratio_pad[1]coords[:, [0, 2]] -= pad[0]  # x paddingcoords[:, [1, 3]] -= pad[1]  # y paddingcoords[:, :4] /= gainclip_coords(coords, img0_shape)return coordsdef clip_coords(boxes, img_shape):# Clip bounding xyxy bounding boxes to image shape (height, width)boxes[:, 0].clip(0, img_shape[1], out=boxes[:, 0])  # x1boxes[:, 1].clip(0, img_shape[0], out=boxes[:, 1])  # y1boxes[:, 2].clip(0, img_shape[1], out=boxes[:, 2])  # x2boxes[:, 3].clip(0, img_shape[0], out=boxes[:, 3])  # y2def detect_postprocess(prediction, img0shape, img1shape, conf_thres=0.25, iou_thres=0.45):'''检测输出后处理prediction: aidlite模型预测输出img0shape: 原始图片shapeimg1shape: 输入图片shapeconf_thres: 置信度阈值iou_thres: IOU阈值return: list[np.ndarray(N, 5)], 对应类别的坐标框信息, xywh、conf'''h, w, _ = img1shapecls_num = prediction.shape[-1] - 5valid_condidates = prediction[prediction[..., 4] > conf_thres]valid_condidates[:, 0] *= wvalid_condidates[:, 1] *= hvalid_condidates[:, 2] *= wvalid_condidates[:, 3] *= hvalid_condidates[:, :4] = xywh2xyxy(valid_condidates[:, :4])valid_condidates = valid_condidates[(valid_condidates[:, 0] > 0) & (valid_condidates[:, 1] > 0) & (valid_condidates[:, 2] > 0) & (valid_condidates[:, 3] > 0)]box_cls = valid_condidates[:, 5:].argmax(1)cls_box = []for i in range(cls_num):temp_boxes = valid_condidates[box_cls == i]if(len(temp_boxes) == 0):cls_box.append([])continuetemp_boxes = NMS(temp_boxes, iou_thres)temp_boxes[:, :4] = scale_coords([h, w], temp_boxes[:, :4] , img0shape).round()temp_boxes[:, :4] = xyxy2xywh(temp_boxes[:, :4])cls_box.append(temp_boxes[:, :5])return cls_boxdef draw_detect_res(img, all_boxes,sign):'''检测结果绘制'''flag = Falseimg = img.astype(np.uint8)color_step = int(255/len(all_boxes))for bi in range(len(all_boxes)):if len(all_boxes[bi]) == 0:continuefor box in all_boxes[bi]:x, y, w, h = [int(t) for t in box[:4]]if bi != sign:continueif bi == sign:flag = Truecv2.putText(img, "Bird detected, start the eviction program", (20, 100),cv2.FONT_HERSHEY_SIMPLEX, 0.5, ( 0, 0 ,255), 1)cv2.putText(img, f'{coco_class[bi]}', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)cv2.rectangle(img, (x,y), (x+w, y+h),(0, bi*color_step, 255-bi*color_step),thickness = 2)return img,flag

yolov5_video源码:

# aidlux相关
from cvs import *
import aidlite_gpu
from utils import detect_postprocess, preprocess_img, draw_detect_resimport time
import requests
import cv2# 加载模型
model_path = 'yolov5s-fp16.tflite'
# 定义输入输出shape
in_shape = [1 * 640 * 640 * 3 * 4]
out_shape = [1 * 25200 * 85 * 4, 1 * 3 * 80 * 80 * 85 * 4, 1 * 3 * 40 * 40 * 85 * 4, 1 * 3 * 20 * 20 * 85 * 4]# 载入模型
aidlite = aidlite_gpu.aidlite()
# 载入yolov5检测模型
aidlite.ANNModel(model_path, in_shape, out_shape, 4, 0)sign = 14   #stop sign:11  bird:14cap = cv2.VideoCapture("bird3.mp4")fps = cap.get(cv2.CAP_PROP_FPS)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# 创建输出视频文件对象fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('output_video3.mp4', fourcc, fps, (width, height))while True:ret ,  frame = cap.read()# if not ret:#     breakif frame is None:break  # 预处理img = preprocess_img(frame, target_shape=(640, 640), div_num=255, means=None, stds=None)aidlite.setInput_Float32(img, 640, 640)# 推理aidlite.invoke()pred = aidlite.getOutput_Float32(0)pred = pred.reshape(1, 25200, 85)[0]pred = detect_postprocess(pred, frame.shape, [640, 640, 3], conf_thres=0.5, iou_thres=0.45)res_img, detec_taget = draw_detect_res(frame, pred, sign)if detec_taget != True :cv2.putText(res_img, "No birds detected, eviction program closed", (20, 100),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 1)# #保存摄像头视频out.write(res_img)cvs.imshow(res_img)cap.release()
out.release()
# 关闭窗口
cv2.destroyAllWindows()#     if detec_taget:  
#         print("区域内有鸟出现,请驱逐")  #     out.write(res_img)  
#     cv2.imshow('Result', res_img)  
#     if cv2.waitKey(1) == ord('q'):  # wait for 'q' key press to quit  
#         break  # cap.release()  
# out.release()  
# cv2.destroyAllWindows()

●操作流程

远程链接Aidlux,并找到home文件夹,将包含上述文件的文件夹上传

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

双击打开yolov5_video.py 并点击Bulid,然后找到Run Now 并点击运行

在这里插入图片描述

或者在终端里cd到yolov5_video.py所在文件夹,用 python yolov5_video.py运行

检测效果图:

在这里插入图片描述

在这里插入图片描述

演示视频:

基于人工智能与边缘计算Aidlux的鸟类检测驱赶系统

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

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

相关文章

数据结构专题2

数据结构专题2 - step 1 线段树 1. Cube - HDU 3584 三维的空间中有 n n n 个元素&#xff0c;初始时每个空间元素均为0。更新操作是0变1&#xff0c;1变0&#xff0c;是一个立方体型区域内的所有元素都更新。然后查询是问某个点的元素是0还是1. ( 1 < n < 100 , m…

java 处理mysql获取树形的数据 带级别和子集数量

要求&#xff1a; 获取数据生成树形数据后&#xff0c;要求返回返回层级&#xff08;level&#xff09;和子集(childCount)的个数&#xff0c;便于前端处理。 处理&#xff1a; 1&#xff0c;在遍历的时候&#xff0c;进行处理。 &#xff08;适合内部调用&#xff09; 2&am…

Java日期操作类

Java中的日期操作类提供了丰富的日期和时间操作功能&#xff0c;可以帮助我们方便地处理日期和时间。本篇技术博客将详细介绍Java日期操作类的定义、使用和示例代码。 Java日期操作类 Java中的日期操作类主要有以下几个&#xff1a; java.util.Datejava.util.Calendarjava.t…

ELK-日志服务【logstash-安装与使用】

目录 【1】安装logstash logstash input 插件的作用与使用方式 【2】input --> stdin插件&#xff1a;从标准输入读取数据&#xff0c;从标准输出中输出内容 【3】input -- > file插件&#xff1a;从文件中读取数据 【4】input -- > beat插件&#xff1a;从filebe…

【Vue2.0源码学习】模板编译篇-模板解析阶段(文本解析器)

文章目录 1. 前言2. 结果分析3. 源码分析4. 总结 1. 前言 在上篇文章中我们说了&#xff0c;当HTML解析器解析到文本内容时会调用4个钩子函数中的chars函数来创建文本型的AST节点&#xff0c;并且也说了在chars函数中会根据文本内容是否包含变量再细分为创建含有变量的AST节点…

开发跨平台APP,是用Flutter还是React Native开发框架?

随着移动互联网的飞速发展&#xff0c;对于开发人员而言&#xff0c;如何快速地开发出兼容不同平台&#xff08;iOS、Android&#xff09;的应用&#xff0c;成为了一个重要的问题。 跨平台应用程序开发框架的好处&#xff1a; 1. 一个App适用于多个设备&#xff1b; 2. 一个…

【CSDN新星计划】初阶牛C/C++赛道——顺序程序设计(C语句②)

目录 3.2 最基本的语句——赋值语句 3.2 最基本的语句——赋值语句 在C程序中最常用的语句是:赋值语句和输入输出语句。其中最基本的是赋值语句程序中的计算功能大部分是由赋值语句实现的,几乎每一个有实用价值的程序都包括赋值语句。有的程序中的大部分语句都是赋值语句。先介…

arcgis实现影像监督分类

1、打开ArcMap,右击空白处打开影像分类工具栏&#xff0c;如下&#xff1a; 2、打开影像&#xff0c;如下&#xff1a; 打开的影像由于未经处理&#xff0c;颜色看起来很昏暗&#xff0c;这时候可以拉伸一下。具体操作&#xff0c;右击图层选择属性&#xff0c;如下&#xff1a…

基于springboot,vue网上订餐系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 前端技术 &#xff1a;VueElementUI 服务端技术&#xff1a;springbootmybatisredis 本系统分用户前台和管理后台两部分&#xff0c;项…

亚马逊评论点赞的作用

在亚马逊上&#xff0c;评论点赞可以起到几个重要的作用&#xff1a; 1、增加可信度&#xff1a;当一个产品或服务有很多积极的评论点赞时&#xff0c;其他用户会更容易相信这些评论的可靠性。点赞数量多的评论通常被认为是由多个用户验证的&#xff0c;并且对于潜在买家来说&…

SpringBoot中注入ServletFilterListener

1.基本介绍 文档&#xff1a;SpringBoot中注入Servlet&Filter&Listener 考虑到实际开发业务非常复杂和兼容问题&#xff0c;SpringBoot支持将Servlet、Filter、Listener注入spring容器中&#xff0c;成为Spring Bean也就是说&#xff0c;SpringBoot开放了和原生WEB组件…

基于单片机智能洗衣机设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;利用STC89C52单片机进行数据处理&#xff1b; 通过2路继电器分别控制洗衣机进水、出水相关逻辑运算&#xff1b;采用L298去掉直流电机实现滚筒正反转&#xff1b;通过单片机进行处理数据&#xff0c;把采集到的数据通过LCD液晶显示…

基于Nonconvex规划的配电网重构研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

网络安全与密码学

1、网络安全威胁 破坏网络安全的一些理论方式&#xff1a; 窃听&#xff1a;窃听信息&#xff0c;在网路通信双方直接进行窃听。 插入&#xff1a;主动在网络连接中插入信息&#xff08;可以在message中插入恶意信息&#xff09; 假冒&#xff1a;伪造&#xff08;spoof&#x…

SQLServer2022安装(Windows),已验证

二、安装可视化工具SSMS 接下来安装可视化工具SSMS&#xff0c;现在新版本默认都是没有可视化界面&#xff0c;需要单独安装 &#xff08;1&#xff09;地址&#xff1a;下载 SQL Server Management Studio (SSMS) - SQL Server Management Studio (SSMS) | Microsoft Learn…

I/O多路复用-redis单线程模型快的根本原因

目录 BIO BIO单线程模式 BIO多线程模型 NIO IO multiplexing select函数&#xff1a; poll函数&#xff1a; epoll函数&#xff1a; 首先了解同步和异步&#xff0c;阻塞和非阻塞的概念&#xff1a; 同步&#xff1a;发起请求的一方需要等待操作完成并获得结果后才能继…

LayUI之CRUD(增删改查)

目录 一、前期准备 1.数据表格 2.弹出层 3.用户表数据查询 二、用户管理后台编写 三、前端JS编写 四、效果展示 一、前期准备 1.数据表格 在layui官网找到我们需要的数据表格 根据需求复制修改代码&#xff0c;再找到表单复制一个输入框和按钮&#xff0c;做一个搜索功能…

React Native 解决 TextInput 设置 maxLength 后,拼音输入法无法输入的问题

目前只发现在 iOS 上存在这个问题&#xff0c;这是由于 iOS 系统的问题&#xff0c;需要添加一个 OC 分类来解决&#xff0c;这里有一个封装好的 react-native-textinput-maxlength-fixed &#xff0c;直接安装即可。 npm install react-native-textinput-maxlength-fixed npx…

数字游民 digital nomad 常见问题解答

目录 什么是数字游民&#xff1f;数字游民是怎么产生的&#xff1f;如何向数字游民转型&#xff1f;常见的数字游民网络聚集地数字游民旅居城市推荐国际版柏林(德国)巴塞罗那(西班牙)布达佩斯(匈牙利)里斯本(葡萄牙)首尔/釜山(韩国) 国内版杭州成都三亚大连厦门 什么是数字游民…

数据仓库-拉链算法

数据仓库-拉链算法&#xff0c;如何处理开链、闭链数据 \timing on set client_encodingGBK; /******程序功能说明*********************************//*****以下根据任务不同进行变量设置*****************/SELECT:AUTO_PDMVIEW AS "PDM_VIEW",:20230710 AS &qu…