次要实现的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_gpufrom utils import detect_postprocess, preprocess_img, draw_detect_res import timeimport cv2 # AidLite初始化:调用AidLite进行AI模型的加载与推理,需导入aidliteaidlite = aidlite_gpu.aidlite()# Aidlite模型门路model_path = '/home/lesson4_codes/aidlux/yolov5n_best-fp16.tflite'# 定义输入输出shapein_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 = 0while 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_gpufrom utils import detect_postprocess, preprocess_img, draw_detect_res #scale_coords,process_points,isInsidePolygon,is_in_polyimport cv2# bytetrackfrom track.tracker.byte_tracker import BYTETrackerfrom 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 = 0while 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_gpufrom utils import detect_postprocess, preprocess_img, draw_detect_res, process_points,is_passing_line    #scale_coords,isInsidePolygon,import cv2# bytetrackfrom track.tracker.byte_tracker import BYTETrackerfrom track.utils.visualize import plot_trackingimport requestsimport 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 = 0count_person=0while 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掉。刚开始我就是没留神到这点,十分苦楚的在那儿找错。