基于AidLux平臺的YOLOV5人流統(tǒng)計項目部署

1.AidLux介紹

1.AidLux是基于ARM架構的跨生態(tài)(Android/鴻蒙+Linux)一站式AIoT應用快速開發(fā)和部署平臺APP

2.通過共享 Linux 內核實現(xiàn)Android 和 Linux 生態(tài)融合暖璧,為單一設備同時提供Android和Linux運行環(huán)境

3.集成國際主流AI框架和多種開發(fā)環(huán)境取胎、后臺服務程序、編譯器及圖形開發(fā)組件忌傻,無須配置開箱即用盔性,極大地簡化了開發(fā)步驟缓醋;自主研發(fā)的AI智能加速技術可實現(xiàn)CPU+GPU+NPU智能加速尽超,大幅提高AI應用運行效率般贼;平臺廣泛而深度的適配外設接口交洗,省去大量調試工作骑科;內置完整的跨平臺桌面和命令行終端連接(SSH),一個平臺完成多終端協(xié)同開發(fā)构拳、測試纵散、部署

4.可使用APK包安裝方式快速部署在ARM架構的手機、平板隐圾、電腦和板卡等智能終端上

5.AidLux能廣泛應用在智能工業(yè)伍掀、AI教育、智慧人居暇藏、智慧城市蜜笤、智慧物流、智慧交通盐碱、智慧零售和機器人等諸多場景中

博主覺得把兔,AidLux最大的優(yōu)勢在于:常規(guī)Al應用開發(fā)需要C++、Java瓮顽、Python县好、Linux等不同工程師相互配合,而在AidLux平臺暖混,開發(fā)者僅需使用Python一種編程語言即可進行開發(fā)缕贡,并支持將其他平臺(PC、服務器)上使用Python開發(fā)的AI應用直接遷移至AidLux調試運行。

也就是說我們只需要熟悉python語言即可晾咪,再也不用學令人頭疼的C++了收擦!

2.環(huán)境搭建

2.1 手機版AidLux的安裝

目前使用Aidlux主要有兩種方式:

1.邊緣設備的方式:阿加犀用高通芯片的S855,和S865制作了兩款邊緣設備谍倦,一款提供7T算力塞赂,一款提供15T算力。

2.手機設備的方式:沒有邊緣設備的情況下昼蛀,也可以使用手機版本的Aidlux宴猾,嘗試邊緣設備的所有功能。

并且目前Aidlux已對基本市面上所有的芯片都進行了適配叼旋,在手機上運行算法模型鳍置,也可以體驗優(yōu)化的效果。當然在使用過程中送淆,有個共同點,即手機設備和邊緣設備采用的Aidlux軟件怕轿,都是一樣的偷崩。因此可以先嘗試手機設備的方式,在后期需要更多算力的時候撞羽,使用邊緣設備阐斜,就可以無縫銜接。所以我們先下載一下手機Aidlux的APP軟件诀紊。打開安卓手機的應用商城谒出,搜索Aidlux即可下載安裝。


?打開手機版本的Aidlux軟件APP邻奠,第一次進入的時候笤喳,APP自帶的系統(tǒng)會進行初始化。


初始化好后碌宴,進入系統(tǒng)登錄頁面杀狡,這一步最好可以用手機注冊一下,當然也可以直接點擊“我已閱讀并同意”贰镣,然后點擊跳過登錄呜象。


注意:軟件獲取存儲權限后會有提示,如果是安卓版本12的手機碑隆,請點擊確認恭陡,跟著提示完成相關步驟,以便后續(xù)開發(fā)上煤。

?進入主頁面后休玩,可以點擊左上角的紅色叉號,將說明頁面關閉。


?為了方便編程哥捕,aidlux還提供了電腦接口(需要手機和電腦連接同一網絡):

?點擊下圖中的Cloud_ip牧抽,即可顯示電腦鏈接



在電腦中輸入第一個網址即可,登陸時需要密碼遥赚,默認密碼為:?aidlux

?登錄成功后可以發(fā)現(xiàn)扬舒,電腦的界面和手機端是同步的:


因此在開發(fā)的時候我們將寫好的代碼上傳到文件中,就可以利用VSCode運行和調試?.

2.2 Aidlux軟件設置默認后臺運行

這里列舉了多款手機設置的方式凫佛,大家可以參照相應的設置教程:

(1)小米手機和平板設置教程:https://community.aidlux.com/postDetail/832

(2)OPPO手機與平板設置教程:https://community.aidlux.com/postDetail/834

(3)vivo手機與平板設置教程:https://community.aidlux.com/postDetail/835

(4)華為鴻蒙/HarmonyOS 2.0設置教程:https://community.aidlux.com/postDetail/828

(5)華為鴻蒙/HarmonyOS 3.0設置教程:https://community.aidlux.com/postDetail/827

2.3 VSCode遠程連接

?新建遠程連接:config如圖所示讲坎,連接的密碼同樣是aidlux


HostName即上文提到的Cloud_ip地址,Port默認9022愧薛,連接成功后晨炕,打開我們上傳到aidlux中的文件夾:

注:打開文件夾的時候會再次輸入密碼 aidlux


接下來就可以通過vscode進行代碼調試了。

3 人流統(tǒng)計實戰(zhàn)

然后我們來看一個運行YOLOv5+目標追蹤bytetrack進行人流統(tǒng)計的案例毫炉,話不多說瓮栗,先上效果:


3.1 目錄結構:


其中yolov5n_best-fp16.tflite是從yolov5訓練好的best.pt權重文件轉換來的。

3.2 相關代碼:

yolov5_overstep.py:


# aidlux相關

from cvs import *

import aidlite_gpu

from utils import detect_postprocess, preprocess_img, draw_detect_res,is_passing_line

import cv2

# bytetrack

from track.tracker.byte_tracker import BYTETracker

from track.utils.visualize import plot_tracking

import requests

import time

# 加載模型

model_path = '/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("/home/lesson5_codes/aidlux/video.mp4")

frame_id = 0

count_person = 0

while True:

? ? frame = cap.read()

? ? if frame is None:

? ? ? ? print('camera is over!')

? ? ? ? # 統(tǒng)計打印人數(shù)流量

? ? ? ? # 填寫對應的喵碼

? ? ? ? id = 'tOqH04S'

? ? ? ? # 填寫喵提醒中瞄勾,發(fā)送的消息费奸,這里放上前面提到的圖片外鏈

? ? ? ? text = "人流統(tǒng)計數(shù):"+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)

? ? # 數(shù)據轉換:因為setTensor_Fp32()需要的是float32類型的數(shù)據,所以送入的input的數(shù)據需為float32,大多數(shù)的開發(fā)者都會忘記將圖像的數(shù)據類型轉換為float32

? ? aidlite.setInput_Float32(img, 640, 640)

? ? # 模型推理API

? ? aidlite.invoke()

? ? # 讀取返回的結果

? ? pred = aidlite.getOutput_Float32(0)

? ? # 數(shù)據維度轉換

? ? 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)

? ? ? ? ? ? ### 人流計數(shù)識別功能實現(xiàn) ###

? ? ? ? ? ? # 1.繪制直線

? ? ? ? ? ? lines = [[186,249],[1235,366]]

? ? ? ? ? ? cv2.line(res_img,(186,249),(1235,266),(255,255,0),3)

? ? ? ? ? ? # 2.計算得到人體下方中心點的位置(人體檢測監(jiān)測點調整)

? ? ? ? ? ? pt = [tlwh[0]+1/2*tlwh[2],tlwh[1]+tlwh[3]]


? ? ? ? ? ? # 3. 人體和違規(guī)區(qū)域的判斷(人體狀態(tài)追蹤判斷)

? ? ? ? ? ? track_info = is_passing_line(pt, lines)

? ? ? ? ? ? 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的狀態(tài)愿阐,上一幀是-1,但是這一幀是1時趾疚,說明越界了

? ? ? ? ? ? if track_id_status[tid][-1] == 1 and len(track_id_status[tid]) >1:

? ? ? ? ? ? ? ? # 判斷上一個狀態(tài)是否是-1缨历,是否的話說明越界,為了防止繼續(xù)判別糙麦,隨機的賦了一個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,105),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,255),2)

? ? cvs.imshow(res_img)? ? ? ? ? ? ?


utils.py:


import time

import cv2

import numpy as np

coco_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 x

? ? y[:, 1] = x[:, 1] - x[:, 3] / 2? # top left y

? ? y[:, 2] = x[:, 0] + x[:, 2] / 2? # bottom right x

? ? y[:, 3] = x[:, 1] + x[:, 3] / 2? # bottom right y

? ? return y

def 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 box

def 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 directly

? ? ? ? keep.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 overlap

? ? ? ? h = np.maximum(0, y22-y11+1)? ? # the height of overlap

? ? ? ? overlaps = w*h

? ? ? ? ious = overlaps / (areas[i]+areas[index[1:]] - overlaps)

? ? ? ? idx = np.where(ious<=thresh)[0]

? ? ? ? index = index[idx+1]? # because index start from 1

? ? return 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 constraints

? ? shape = 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 padding

? ? ratio = r, r? # width, height ratios

? ? new_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 padding

? ? if auto:? # minimum rectangle

? ? ? ? dw, dh = np.mod(dw, stride), np.mod(dh, stride)? # wh padding

? ? elif scaleFill:? # stretch

? ? ? ? dw, dh = 0.0, 0.0

? ? ? ? new_unpad = (new_shape[1], new_shape[0])

? ? ? ? ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]? # width, height ratios

? ? dw /= 2? # divide padding into 2 sides

? ? dh /= 2

? ? if shape[::-1] != new_unpad:? # resize

? ? ? ? img = 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 border

? ? return 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: 目標shape

? ? div_num: 歸一化除數(shù)

? ? means: len(means)==圖像通道數(shù)辛孵,通道均值, None不進行zscore

? ? stds: len(stds)==圖像通道數(shù),通道方差, None不進行zscore

? ? '''

? ? img_processed = np.copy(img)

? ? # resize

? ? if 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-score

? ? if 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

? ? # unsqueeze

? ? img_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 4

? ? ? ? for n in shape:

? ? ? ? ? ? nums *= n

? ? ? ? out.append(nums)

? ? return out

def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):

? ? # Rescale coords (xyxy) from img1_shape to img0_shape

? ? if ratio_pad is None:? # calculate from img0_shape

? ? ? ? gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1])? # gain? = old / new

? ? ? ? pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2? # wh padding

? ? else:

? ? ? ? gain = ratio_pad[0][0]

? ? ? ? pad = ratio_pad[1]

? ? coords[:, [0, 2]] -= pad[0]? # x padding

? ? coords[:, [1, 3]] -= pad[1]? # y padding

? ? coords[:, :4] /= gain

? ? clip_coords(coords, img0_shape)

? ? return coords

def 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])? # x1

? ? boxes[:, 1].clip(0, img_shape[0], out=boxes[:, 1])? # y1

? ? boxes[:, 2].clip(0, img_shape[1], out=boxes[:, 2])? # x2

? ? boxes[:, 3].clip(0, img_shape[0], out=boxes[:, 3])? # y2

def detect_postprocess(prediction, img0shape, img1shape, conf_thres=0.25, iou_thres=0.45):

? ? '''

? ? 檢測輸出后處理

? ? prediction: aidlite模型預測輸出

? ? img0shape: 原始圖片shape

? ? img1shape: 輸入圖片shape

? ? conf_thres: 置信度閾值

? ? iou_thres: IOU閾值

? ? return: list[np.ndarray(N, 5)], 對應類別的坐標框信息, xywh赡磅、conf

? ? '''

? ? h, w, _ = img1shape

? ? cls_num = prediction.shape[-1] - 5

? ? valid_condidates = prediction[prediction[..., 4] > conf_thres]

? ? valid_condidates[:, 0] *= w

? ? valid_condidates[:, 1] *= h

? ? valid_condidates[:, 2] *= w

? ? valid_condidates[:, 3] *= h

? ? valid_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([])

? ? ? ? ? ? continue

? ? ? ? temp_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_box

def draw_detect_res(img, all_boxes):

? ? '''

? ? 檢測結果繪制

? ? '''

? ? img = img.astype(np.uint8)

? ? color_step = int(255/len(all_boxes))

? ? for bi in range(len(all_boxes)):

? ? ? ? if len(all_boxes[bi]) == 0:

? ? ? ? ? ? continue

? ? ? ? for box in all_boxes[bi]:

? ? ? ? ? ? x, y, w, h = [int(t) for t in box[:4]]

? ? ? ? ? ? score = str(box[4:5][0])

? ? ? ? ? ? cv2.putText(img, str(round(float(score),2)), (x, y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (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

def process_points(img,points,color_light_green):

? ? points = np.array([points], dtype=np.int32)

? ? ###繪制mask

? ? zeros = np.zeros((img.shape), dtype=np.uint8)

? ? mask = cv2.fillPoly(zeros, points, color=color_light_green)? ####填充顏色

? ? ##繪制輪廓

? ? cv2.drawContours(img, points, -1, (144, 238, 144), 5)? ###繪制輪廓

? ? ##疊加mask和普通圖片

? ? mask_img = 0.01 * mask + img

? ? return mask_img

def is_in_poly(p, poly):

? ? """

? ? :param p: [x, y]

? ? :param poly: [[], [], [], [], ...]

? ? :return:

? ? """

? ? px, py = p

? ? is_in = False

? ? for i, corner in enumerate(poly):

? ? ? ? next_i = i + 1 if i + 1 < len(poly) else 0

? ? ? ? x1, y1 = corner

? ? ? ? x2, y2 = poly[next_i]

? ? ? ? if (x1 == px and y1 == py) or (x2 == px and y2 == py):? # if point is on vertex

? ? ? ? ? ? is_in = True

? ? ? ? ? ? break

? ? ? ? if min(y1, y2) < py <= max(y1, y2):? # find horizontal edges of polygon

? ? ? ? ? ? x = x1 + (py - y1) * (x2 - x1) / (y2 - y1)

? ? ? ? ? ? if x == px:? # if point is on edge

? ? ? ? ? ? ? ? is_in = True

? ? ? ? ? ? ? ? break

? ? ? ? ? ? elif x > px:? # if point is on left-side of line

? ? ? ? ? ? ? ? is_in = not is_in

? ? if is_in == True:

? ? ? ? person_status = 1

? ? else:

? ? ? ? person_status = -1

? ? return person_status

def is_passing_line(point, polyline):

? ? # 在直線下方,status =-1

? ? # 在直線上方,status =1

? ? status = 1

? ? # 點映射在直線的高度

? ? poly_y = ((polyline[1][1] - polyline[0][1]) * (point[0] - polyline[0][0])) / (polyline[1][0] - polyline[0][0]) + \

? ? ? ? ? ? ? polyline[0][1]

? ? if point[1] > poly_y:

? ? ? ? status = -1

? ? return status


3.3喵提醒公眾號的使用

?在yolov5_overstep.py中我們可以看到觉吭,有這樣一段代碼:

它可以用來實現(xiàn)如下效果:

即:當我們預測完一段視頻,或者一個時段之后仆邓,通過公眾號通知我們人流量為多少鲜滩。

使用方法我們已經在上面給出,大家只需要把喵碼ID換成自己的节值,這樣才會發(fā)送到自己的微信上徙硅。

下面來介紹一下如何獲取喵碼id:

(1)關注“喵提醒”公眾號,關注成功后搞疗,公眾號會給我們發(fā)送一條消息嗓蘑,可以直接點擊注冊賬號须肆,或者給公眾號發(fā)送“注冊賬號”。


?(2)在底部菜單欄中桩皿,點擊提醒--新建


(3)填寫完標題和備注后豌汇,點擊保存,系統(tǒng)會自動生成喵碼id泄隔。

?(4)此時拒贱,我們只需要復制喵碼id,并且替換代碼中原有的id即可

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末佛嬉,一起剝皮案震驚了整個濱河市逻澳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌暖呕,老刑警劉巖斜做,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異湾揽,居然都是意外死亡瓤逼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門库物,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霸旗,“玉大人,你說我怎么就攤上這事艳狐。” “怎么了皿桑?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵毫目,是天一觀的道長。 經常有香客問我诲侮,道長镀虐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任沟绪,我火速辦了婚禮刮便,結果婚禮上,老公的妹妹穿的比我還像新娘绽慈。我一直安慰自己恨旱,他們只是感情好,可當我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布坝疼。 她就那樣靜靜地躺著搜贤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钝凶。 梳的紋絲不亂的頭發(fā)上仪芒,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機與錄音,去河邊找鬼掂名。 笑死据沈,一個胖子當著我的面吹牛,可吹牛的內容都是我干的饺蔑。 我是一名探鬼主播锌介,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膀钠!你這毒婦竟也來了掏湾?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤肿嘲,失蹤者是張志新(化名)和其女友劉穎融击,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雳窟,經...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡尊浪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了封救。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拇涤。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖誉结,靈堂內的尸體忽然破棺而出鹅士,到底是詐尸還是另有隱情,我是刑警寧澤惩坑,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布掉盅,位于F島的核電站,受9級特大地震影響以舒,放射性物質發(fā)生泄漏趾痘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一蔓钟、第九天 我趴在偏房一處隱蔽的房頂上張望永票。 院中可真熱鬧,春花似錦滥沫、人聲如沸侣集。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肚吏。三九已至,卻和暖如春狭魂,著一層夾襖步出監(jiān)牢的瞬間罚攀,已是汗流浹背党觅。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留斋泄,地道東北人杯瞻。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像炫掐,于是被迫代替她去往敵國和親魁莉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內容