共计 9487 个字符,预计需要花费 24 分钟才能阅读完成。
次要实现的 AI 算法有:指标检测、指标追踪
次要实现 AI 算法性能:越界辨认性能(次要是获取统计人流量)
平台:基于 Aidlux 平台
根底库装置:
(1)lap 装置:
先 sudo apt-get update,再输出 sudo apt-get install -y cmake build-essential python3-dev;最初 pip install lap -i https://pypi.tuna.tsinghua.ed…。
(2)cython_bbox 装置:
先装置 cython:pip install cython -i https://pypi.tuna.tsinghua.ed…
再装置 cython_bbox:pip install cython_bbox -i https://pypi.tuna.tsinghua.ed…
(3)torch 装置:
pip install torch -i https://pypi.tuna.tsinghua.ed…,如果有装置过则跳过。
(4)torchvision 装置:
pip install torchvision -i https://pypi.tuna.tsinghua.ed…,如果有装置过,则跳过。
(5)thop 装置:
pip install thop -i https://pypi.tuna.tsinghua.ed…
一、前提:
咱们通常学习的 AI 视觉算法,次要是底层的利用技术,比方指标检测、人脸识别、图像宰割、关键点检测、语音辨认、OCR 辨认等算法。通常而言,在各个行业理论利用中,不同的场景,对应不同的算法性能,而不同的算法性能则由不同利用技术组合而成。如下图:
而明天这个人流量的统计利用次要用到的 AI 算法性能是越界辨认,它次要是由基于 yolov5 框架的指标检测算法和基于 Bytetrack 多指标追踪算法(当然应用 Deepsort 多指标追踪算法也是能够的)
以下是论文地址分享:
Deepsort 多指标追踪算法论文 PDF:
http://extension//idghocbbaha…
Bytetrack 多指标追踪算法论文 PDF:
http://extension//idghocbbaha…
代码实现:
指标检测模块(次要是基于 yolov5):
关上 yolov5.py 进行视频推理测试
# aidlux 相干
from cvs import *
import aidlite_gpu
from utils import detect_postprocess, preprocess_img, draw_detect_res
import time
import cv2
# AidLite 初始化:调用 AidLite 进行 AI 模型的加载与推理,需导入 aidlite
aidlite = aidlite_gpu.aidlite()
# Aidlite 模型门路
model_path = '/home/lesson4_codes/aidlux/yolov5n_best-fp16.tflite'
# 定义输入输出 shape
in_shape = [1 * 640 * 640 * 3 * 4]
out_shape = [1 * 25200 * 6 * 4]
# 加载 Aidlite 检测模型:反对 tflite, tnn, mnn, ms, nb 格局的模型加载
aidlite.ANNModel(model_path, in_shape, out_shape, 4, 0)
cap = cvs.VideoCapture("/home/lesson4_codes/aidlux/market.mp4")
frame_id = 0
while True:
frame = cap.read()
if frame is None:
continue
frame_id += 1
if not int(frame_id) % 5 == 0: continue
# 预处理
img = preprocess_img(frame, target_shape=(640, 640), div_num=255, means=None, stds=None)
# 数据转换:因为 setTensor_Fp32()须要的是 float32 类型的数据,所以送入的 input 的数据需为 float32, 大多数的开发者都会遗记将图像的数据类型转换为 float32
aidlite.setInput_Float32(img, 640, 640)
# 模型推理 API
aidlite.invoke()
# 读取返回的后果
pred = aidlite.getOutput_Float32(0)
# 数据维度转换
pred = pred.reshape(1, 25200, 6)[0]
# 模型推理后处理
pred = detect_postprocess(pred, frame.shape, [640, 640, 3], conf_thres=0.5, iou_thres=0.45)
# 绘制推理后果
res_img = draw_detect_res(frame, pred)
cvs.imshow(res_img)
成果截图:
标签中的 person 代表是人,分数代表的是置信度也等同于说这个框内的物体是人的概率值。
指标追踪模块(次要是基于 Bytetrack 多指标追踪算法):
关上 yolov5_bytetrack.py 进行视频推理测试
from cvs import *
import aidlite_gpu
from utils import detect_postprocess, preprocess_img, draw_detect_res #scale_coords,process_points,isInsidePolygon,is_in_poly
import cv2
# bytetrack
from track.tracker.byte_tracker import BYTETracker
from track.utils.visualize import plot_tracking
# 加载模型
model_path = r'/home/lesson5_codes/aidlux/yolov5n_best-fp16.tflite'
in_shape = [1 * 640 * 640 * 3 * 4]
out_shape = [1 * 25200 * 6 * 4]
# 载入模型
aidlite = aidlite_gpu.aidlite()
# 载入 yolov5 检测模型
aidlite.ANNModel(model_path, in_shape, out_shape, 4, 0)
tracker = BYTETracker(frame_rate=30)
track_id_status = {}
cap = cvs.VideoCapture(r"/home/lesson5_codes/aidlux/videotest1.mp4")
frame_id = 0
while True:
frame = cap.read()
if frame is None:
continue
frame_id += 1
if frame_id % 3 != 0:
continue
# 预处理
img = preprocess_img(frame, target_shape=(640, 640), div_num=255, means=None, stds=None)
# 数据转换:因为 setTensor_Fp32()须要的是 float32 类型的数据,所以送入的 input 的数据需为 float32, 大多数的开发者都会遗记将图像的数据类型转换为 float32
aidlite.setInput_Float32(img, 640, 640)
# 模型推理 API
aidlite.invoke()
# 读取返回的后果
pred = aidlite.getOutput_Float32(0)
# 数据维度转换
pred = pred.reshape(1, 25200, 6)[0]
# 模型推理后处理
pred = detect_postprocess(pred, frame.shape, [640, 640, 3], conf_thres=0.4, iou_thres=0.45)
# 绘制推理后果
res_img = draw_detect_res(frame, pred)
# 指标追踪相干性能
det = []
# Process predictions
for box in pred[0]: # per image
box[2] += box[0]
box[3] += box[1]
det.append(box)
if len(det):
# Rescale boxes from img_size to im0 size
online_targets = tracker.update(det, [frame.shape[0], frame.shape[1]])
online_tlwhs = []
online_ids = []
online_scores = []
# 取出每个指标的追踪信息
for t in online_targets:
# 指标的检测框信息
tlwh = t.tlwh
# 指标的 track_id 信息
tid = t.track_id
online_tlwhs.append(tlwh)
online_ids.append(tid)
online_scores.append(t.score)
# 针对指标绘制追踪相干信息
res_img = plot_tracking(res_img, online_tlwhs, online_ids, 0,0)
cvs.imshow(res_img)
成果截图:
![上传中 …]()
标签上的蓝色数字为 track_id,能够了解为每个人框的 id 号,代表着一个物体,红色数字则为置信度。
实现人流数量统计性能:
将物体检测模块与物体追踪模块相结合:
代码如下:
from cvs import *
import aidlite_gpu
from utils import detect_postprocess, preprocess_img, draw_detect_res, process_points,is_passing_line #scale_coords,isInsidePolygon,
import cv2
# bytetrack
from track.tracker.byte_tracker import BYTETracker
from track.utils.visualize import plot_tracking
import requests
import time
# 加载模型
model_path = '/home/lesson4_codes/aidlux/yolov5n_best-fp16.tflite'
in_shape = [1 * 640 * 640 * 3 * 4]
out_shape = [1 * 25200 * 6 * 4]
# 载入模型
aidlite = aidlite_gpu.aidlite()
# 载入 yolov5 检测模型
aidlite.ANNModel(model_path, in_shape, out_shape, 4, 0)
tracker = BYTETracker(frame_rate=30)
track_id_status = {}
cap = cvs.VideoCapture(r"/home/lesson5_codes/aidlux/videotest1.mp4")
frame_id = 0
count_person=0
while True:
frame = cap.read()
if frame is None:
### 相机采集后果 ###
print("camer is over!")
### 统计打印人流数量 ###
# 填写对应的喵码
id = '******'
# 填写喵揭示中,发送的音讯,这里放上后面提到的图片外链
text = "人数统计:"+str(count_person)
ts = str(time.time()) # 工夫戳
type = 'json' # 返回内容格局
request_url = "http://miaotixing.com/trigger?"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47'}
result = requests.post(request_url + "id=" + id + "&text=" + text + "&ts=" + ts + "&type=" + type,headers=headers)
break
frame_id += 1
if frame_id % 3 != 0:
continue
# 预处理
img = preprocess_img(frame, target_shape=(640, 640), div_num=255, means=None, stds=None)
# 数据转换:因为 setTensor_Fp32()须要的是 float32 类型的数据,所以送入的 input 的数据需为 float32, 大多数的开发者都会遗记将图像的数据类型转换为 float32
aidlite.setInput_Float32(img, 640, 640)
# 模型推理 API
aidlite.invoke()
# 读取返回的后果
pred = aidlite.getOutput_Float32(0)
# 数据维度转换
pred = pred.reshape(1, 25200, 6)[0]
# 模型推理后处理
pred = detect_postprocess(pred, frame.shape, [640, 640, 3], conf_thres=0.4, iou_thres=0.45)
# 绘制推理后果
res_img = draw_detect_res(frame, pred)
# 指标追踪相干性能
det = []
# Process predictions
for box in pred[0]: # per image
box[2] += box[0]
box[3] += box[1]
det.append(box)
if len(det):
# Rescale boxes from img_size to im0 size
online_targets = tracker.update(det, [frame.shape[0], frame.shape[1]])
online_tlwhs = []
online_ids = []
online_scores = []
# 取出每个指标的追踪信息
for t in online_targets:
# 指标的检测框信息
tlwh = t.tlwh
# 指标的 track_id 信息
tid = t.track_id
online_tlwhs.append(tlwh)
online_ids.append(tid)
online_scores.append(t.score)
# 针对指标绘制追踪相干信息
res_img = plot_tracking(res_img, online_tlwhs, online_ids, 0,0)
### 越界辨认性能实现 ###
# 1. 绘制越界监测区域
points = [[204,453],[1274,455]]
color_light_green=(255, 0, 0) ## 绿色
res_img = process_points(res_img,points,color_light_green)
# 2. 计算失去人体下方中心点的地位(人体检测监测点调整)pt = [tlwh[0]+1/2*tlwh[2],tlwh[1]+tlwh[3]]
# 3. 人体和违规区域的判断(人体状态追踪判断)track_info = is_passing_line(pt, points)
if tid not in track_id_status.keys():
track_id_status.update({tid:[track_info]})
else:
if track_info != track_id_status[tid][-1]:
track_id_status[tid].append(track_info)
# 4. 判断是否有 track_id 越界,有的话保留成图片
# 当某个 track_id 的状态,上一帧是 -1,然而这一帧是 1 时,阐明越界了
if track_id_status[tid][-1] == 1 and len(track_id_status[tid]) >1:
# 判断上一个状态是否是 -1,是否的话阐明越界,为了避免持续判断,随机的赋了一个 3 的值
if track_id_status[tid][-2] == -1:
track_id_status[tid].append(3)
count_person+=1
cv2.putText(res_img,"-1 to 1 person_count:"+str(count_person),(50,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
cvs.imshow(res_img)
实现成果:
每有一个人通过那条绿线,person_count 就会增 1,最初人数统计完后,会通过喵揭示性能,将统计人数发送到手机微信端:
其实整体实现的逻辑也很简略,次要分为五个局部:
(1)人流统计越界限段绘制
# 1. 绘制越界监测区域
points = [[204,453],[1274,455]]
color_light_green=(255, 0, 0) ## 绿色
res_img = process_points(res_img,points,color_light_green)
(2)人体检测统计点调整
次要剖析人体下方中心点,和人流统计线段的地位关系。检测框的四个点信息,[左上角点 x,左上角点 y,宽 w,高 h]。所以咱们须要通过代码,转换成人体下方的点,即[左上角点 x +1/2* 宽 w,左上角点 y + 高 h]。
# 2. 计算失去人体下方中心点的地位(人体检测监测点调整)pt = [tlwh[0]+1/2*tlwh[2],tlwh[1]+tlwh[3]]
3)人体和线段的地位状态判断
这里次要剖析人体下方点,和统计线段的地位关系,这部分的代码在 utils.py 的 is_passing_line 函数中。当人体在线段的下方时,人体状态是 -1。当人体在线段的上方时,人体状态是 1。
# 3. 人体和违规区域的判断(人体状态追踪判断)track_info = is_passing_line(pt, points)
if tid not in track_id_status.keys():
track_id_status.update({tid:[track_info]})
else:
if track_info != track_id_status[tid][-1]:
track_id_status[tid].append(track_info)
(4)人流统计分析判断
那么当人体的状态,从 - 1 变动到 1 的时候,就统计成为人员越线了。
4. 判断是否有 track_id 越界
# 当某个 track_id 的状态,上一帧是 -1,然而这一帧是 1 时,阐明越界了
if track_id_status[tid][-1] == 1 and len(track_id_status[tid]) >1:
# 判断上一个状态是否是 -1,是否的话阐明越界,为了避免持续判断,随机的赋了一个 3 的值
if track_id_status[tid][-2] == -1:
track_id_status[tid].append(3)
count_person+=1
(5)喵揭示发送
当整个视频跑完后,就能够失去人流统计整体的数据了。为了及时晓得人流的信息状态,咱们也能够将最初的后果,以喵揭示的形式进行发送。
if frame is None:
### 相机采集后果 ###
print("camer is over!")
### 统计打印人流数量 ###
# 填写对应的喵码
id = '******'
# 填写喵揭示中,发送的音讯,这里放上后面提到的图片外链
text = "人数统计:"+str(count_person)
ts = str(time.time()) # 工夫戳
type = 'json' # 返回内容格局
request_url = "http://miaotixing.com/trigger?"
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36 Edg/87.0.664.47'}
result = requests.post(request_url + "id=" + id + "&text=" + text + "&ts=" + ts + "&type=" + type,headers=headers)
break
目前只是简略的介绍了各个模块的相应性能,因为篇幅较多,后续会对每个相应模块进行搭建和具体代码解释。
学习心得
刚开始进行代码实际操作时,对我的项目的搭建有点吃力,尤其是刚开始对 AidLux 平台中的环境配置时,因为第一次应用,不太熟悉操作,破费了很多工夫,不过幸好江大白老师十分急躁的给予解答,才事倍功半,同时通过一阵子的学习也造就了我 debug 程序的能力,这段时间通过对 yolo 框架源码的学习以及论文的浏览,大大的进步了我对 yolo 框架的认知和应用(尽管用的并不是那么纯熟)
AidLux 应用心得
先介绍下什么是 AidLux?
本次人流统计我的项目应用到了 AidLux 平台,等同于大家所说的边缘设施,尽管用的是边缘设施,然而却是以安卓和 Linux 双系统的形式,只应用 Python 就能对算法减速优化。通常 AI 我的项目边缘设施落地计划有很多,AI 边缘设施是十分重要的算力载体设施。其中十分要害的,就是 AI 芯片,当然市面上的销售形式,次要有两种:
(1)AI 芯片模组:公司自研 AI 芯片,比方寒武纪,对外销售的次要是 AI 芯片模组,由一些内部的设施公司再集成到边缘设施或者工控机,以设施公司的品牌对外销售;
(2)AI 边缘设施:以销售 AI 边缘设施为主,比方英伟达,算能科技,阿加犀。通常会自研或者洽购 AI 芯片,并以 AI 边缘设施的状态对外销售,为很多 AI 解决方案公司提供算力设施;当然其中的一些自研 AI 芯片的公司,除了边缘设施之外,也会提供 AI 芯片 / 模组方面的产品,间接对外销售,比方算能科技。
当然一般来说,想要玩转边缘设施,通常会开发一整套的视频结构化性能。通过 C ++ 的形式调用算力,将须要解决的结构化信息输入,比方编程 Json 模式,为前面的业务解决提供剖析的信息。惯例来说,市面上所有的边缘设施,次要是以 C ++ 的形式来进行开发。不过这里应用的另外一种边缘设施开发的计划,即以 Python 的形式。益处在于,算法工程师应用 Python 开发的模型,能够间接无缝连接来持续开发利用了。比方采纳 AidBox GS865 边缘设施。
这里所说的边缘设施 AidBox,次要是采纳高通 ARM 端芯片开发的。不过咱们在学习的时候,都没有 AidBox 边缘设施硬件。因而也能够采纳另外一种思路,即 AidLux 边缘设施软件,这个环境和事实的边缘计算设施 AidBox 根本一样。
当然 AidLux 中还存在着一些小 bug 和适配的问题,比方我的手机是安卓 12 的,当 AidLux 后端运行时经常会被手机零碎清理掉,就算我设置为白名单也不行。前面须要应用开发者调试进行批改。当运行了代码时,你会在手机版本的 Aidlux 和 PC 端网页的 Aidlux 中,都能够看到推理的显示后果,须要留神的是,在运行的时候,须要把手机版本外面的 aidlux 页面叉掉,不然可能会有抵触,运行的线程会间接被 killed 掉。刚开始我就是没留神到这点,十分苦楚的在那儿找错。