基于人工智能与边缘计算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.hqwc.cn/news/2271.html

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

相关文章

Kotlin Jetpack Compose - 实现Tab布局

Tab布局是一种常见的UI设计&#xff0c;它允许用户在不同的视图或数据集之间切换。我们将使用Jetpack Compose的 TabRow 和 ScrollableTabRow 组件来实现这个布局。 一、基本的Tab布局——TabRow 二、滚动的Tab布局——ScrollableTabRow 组件 三、自定义Tab组件 一、基本的T…

appium如何连接多台设备

目录 前言&#xff1a; 1.我们拿两台设备来模拟操作下&#xff0c;使用&#xff1a;adb devices查看连接状况&#xff0c;获取到设备名称。 2.获取需要操作app的包名和页面名称&#xff08;前提该设备已经打开了app&#xff09; 3.设置初始配置信息 4.打开页面后操作元素&am…

Spring MVC相关注解运用 —— 上篇

目录 一、Controller、RequestMapping 1.1 示例程序 1.2 测试结果 二、RequestParam 2.1 示例程序 2.2 测试结果 三、RequestHeader、CookieValue 3.1 示例程序 3.2 测试结果 四、SessionAttributes 4.1 示例程序 4.2 测试结果 五、ModelAttribute 5.1 示例程序 …

A核与M核异构通信过程解析

现在越来越多的产品具有M core和A core的异构架构&#xff0c;既能达到M核的实时要求&#xff0c;又能满足A核的生态和算力。比如NXP的i.MX8系列、瑞萨的RZ/G2L系列以及TI的AM62x系列等等。虽然这些处理器的品牌及性能有所不同&#xff0c;但多核通信原理基本一致&#xff0c;都…

Spring Boot中的SimpMessagingTemplate是什么,原理,以及如何使用

Spring Boot中的SimpMessagingTemplate是什么&#xff0c;原理&#xff0c;以及如何使用 SimpMessagingTemplate是Spring Framework中的一个类&#xff0c;用于向WebSocket客户端发送消息。在Spring Boot应用程序中&#xff0c;可以使用SimpMessagingTemplate来实现WebSocket通…

OpenCV 学习笔记(C++)(1.4W字)

一切图像皆Mat OpenCV中图像对象的创建与复制 Mat基本结构 Mat对象数据组成&#xff1a;头部和数据部分&#xff0c;头部存储图像的属性&#xff08;大小、宽高、图像类型&#xff1a;浮点数类型、字节类型、16位整型、32位整型、双精度浮点型&#xff0c;通道数量和获取途径…

【微服务】什么是微服务?-- 全面了解微服务架构

What is Microservices — Edureka 您有没有想过&#xff0c;什么是微服务以及扩展行业如何与它们集成&#xff0c;同时构建应用程序以满足客户的期望&#xff1f; 要了解什么是微服务&#xff0c;您必须了解如何将单体应用程序分解为独立打包和部署的小型微型应用程序。本文将…

在windows server上用Mosquitto软件创建MQTT服务器

今天下午捣鼓了半天&#xff0c;在云服务器上面创建了个MQTT服务器&#xff0c;然后用MQTTX软件进行了测试。过程记录如下&#xff1a; 1、下载mosquitto软件&#xff0c;链接如下图&#xff1a; 2、下载完成后安装&#xff0c;一直点下一步下一步就好了。 3、在安装路径下&am…

CHATGPT使用笔记

CHATGPT是帮你做事&#xff0c;而不是替你做事 1、联网插件&#xff1a; 使用Webpilot插件联网时还可以同时使用其它两种插件&#xff08;一次可以同时使用三个插件&#xff09;&#xff0c;而使用Web Browsing插件功能联网时无法使用插件功能&#xff08;联网功能和插件只能…

Celery分布式异步框架

Celery异步任务框架 """ 1&#xff09;可以不依赖任何服务器&#xff0c;通过自身命令&#xff0c;启动服务(内部支持socket) 2&#xff09;celery服务为为其他项目服务提供异步解决任务需求的 注&#xff1a;会有两个服务同时运行&#xff0c;一个是项目服务&a…

基于SpringCloud微服务流动资金贷款业务系统设计与实现

一、引言 由于传统的贷款业务系统并不能够顺应时代的变化,同时在一定程度上对业务发展进行了限制,所以为了适应时代的发展,信息贷款业务应该能够被产品化、丰富化,同时还需要制定一套特定的流程来满足新时代用户的需求。流程化的规范管理是当今银行业务发展的必然趋势,研究并开…

Linux--获取一长串目录的结构指令:tree

注意&#xff1a;这个tree指令不是Linux自带的&#xff0c;需要下载 yum install -y tree (-y的作用是免确定) 示例&#xff1a;