You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
11 KiB
279 lines
11 KiB
import cv2
|
|
import numpy as np
|
|
from numpy.core.fromnumeric import size
|
|
import ec.warningunit
|
|
# 设置窗体大小
|
|
img_size=(1920,1080)
|
|
# class names
|
|
clsnames= [ '行 人', '自行车', '小汽车', '摩托车', 'airplane', '巴 士', 'train', '卡 车', 'boat', 'traffic light',
|
|
'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', '狗', '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' ]
|
|
# class names
|
|
# names= [ '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' ]
|
|
# 根据视频尺寸,填充一个polygon,供撞线计算使用
|
|
mask_image_temp = np.zeros((1080, 1920), dtype=np.uint8)
|
|
|
|
# 初始化2个撞线polygon
|
|
# list_pts_blue = [[204, 305], [227, 431], [605, 522], [1101, 464], [1910, 491], [1910, 400], [1125, 379], [604, 437],
|
|
# [299, 375], [267, 289]]
|
|
top=300
|
|
height =50
|
|
# # 测试
|
|
list_pts_blue = [[10, 300], [560, 350], [1200, 400], [1910, 350],
|
|
[1918, 500], [1250, 550], [580, 500], [10, 450]]
|
|
|
|
# #横琴大桥
|
|
# list_pts_blue = [ [850,850], [1240, 510],
|
|
# [1370, 580], [950, 950]]
|
|
#横琴新家园
|
|
# list_pts_blue = [ [100,600], [1400, 600],
|
|
# [1500, 700], [200, 700]]
|
|
ndarray_pts_blue = np.array(list_pts_blue, np.int32)
|
|
ndarray_pts_blue =ndarray_pts_blue+np.array([0,-260])#
|
|
polygon_blue_value_1 = cv2.fillPoly(mask_image_temp, [ndarray_pts_blue], color=1)
|
|
polygon_blue_value_1 = polygon_blue_value_1[:, :, np.newaxis]
|
|
|
|
# 填充第二个polygon
|
|
mask_image_temp = np.zeros((1080, 1920), dtype=np.uint8)
|
|
# list_pts_yellow =list_pts_blue +[[0,30]]
|
|
ndarray_pts_yellow =ndarray_pts_blue+np.array([0,160])# np.array(list_pts_yellow, np.int32)
|
|
# ndarray_pts_yellow =ndarray_pts_blue+np.array([130,80])# np.array(list_pts_yellow, np.int32)
|
|
# ndarray_pts_yellow =ndarray_pts_blue+np.array([100,100])# np.array(list_pts_yellow, np.int32)
|
|
polygon_yellow_value_2 = cv2.fillPoly(mask_image_temp, [ndarray_pts_yellow], color=2)
|
|
polygon_yellow_value_2 = polygon_yellow_value_2[:, :, np.newaxis]
|
|
|
|
# 撞线检测用mask,包含2个polygon,(值范围 0、1、2),供撞线计算使用
|
|
polygon_mask_blue_and_yellow = polygon_blue_value_1 + polygon_yellow_value_2
|
|
|
|
# 缩小尺寸,1920x1080->960x540
|
|
polygon_mask_blue_and_yellow = cv2.resize(polygon_mask_blue_and_yellow, img_size)
|
|
|
|
# 蓝 色盘 b,g,r
|
|
blue_color_plate = [255, 0, 0]
|
|
# 蓝 polygon图片
|
|
blue_image = np.array(polygon_blue_value_1 * blue_color_plate, np.uint8)
|
|
|
|
# 黄 色盘
|
|
yellow_color_plate = [0, 255, 255]
|
|
# 黄 polygon图片
|
|
yellow_image = np.array(polygon_yellow_value_2 * yellow_color_plate, np.uint8)
|
|
|
|
# 彩色图片(值范围 0-255)
|
|
color_polygons_image = blue_image + yellow_image
|
|
# 缩小尺寸,1920x1080->960x540
|
|
color_polygons_image = cv2.resize(color_polygons_image,img_size)
|
|
|
|
# list 与蓝色polygon重叠
|
|
list_overlapping_blue_polygon = []
|
|
|
|
# list 与黄色polygon重叠
|
|
list_overlapping_yellow_polygon = []
|
|
countlist=[]
|
|
|
|
|
|
|
|
def addcountup( cls_id):
|
|
|
|
for modex in countlist:
|
|
if modex["key"]==cls_id:
|
|
modex["up"]+=1
|
|
return modex
|
|
modex ={}
|
|
modex["key"]=cls_id
|
|
modex["up"]=1
|
|
modex["down"]=0
|
|
countlist.append(modex)
|
|
|
|
return modex
|
|
def addcountdown(cls_id):
|
|
|
|
for modex in countlist:
|
|
if modex["key"]==cls_id:
|
|
modex["down"]+=1
|
|
return modex
|
|
modex ={}
|
|
modex["key"]=cls_id
|
|
modex["up"]=0
|
|
modex["down"]=1
|
|
countlist.append(modex)
|
|
return modex
|
|
font_draw_number =cv2.FONT_HERSHEY_SIMPLEX#FONT_HERSHEY_SIMPLEX
|
|
|
|
# def drawcounttext(output_image_frame):
|
|
# blk = np.zeros(output_image_frame.shape, np.uint8)
|
|
|
|
# cv2.rectangle(blk,(0, 0), (250, 100), (255, 255, 255), -1) # 注意在 blk的基础上进行绘制;
|
|
# # output_image_frame = cv2.addWeighted(output_image_frame, 1.0, blk, 0.5, 1)
|
|
# alpha = 1
|
|
# # beta 为第二张图片的透明度
|
|
# beta = 0.5
|
|
# gamma = 0
|
|
# # cv2.addWeighted 将原始图片与 mask 融合
|
|
# output_image_frame = cv2.addWeighted(output_image_frame, alpha, blk, beta, gamma)
|
|
|
|
# row =0
|
|
# for modex in countlist:
|
|
# draw_text_postion = (10, int(20+row*25))
|
|
# # text_draw =tracker.names[modex["key"]]+" in:"+str(modex["up"])+": out:"+str(modex["down"])
|
|
# # cv2.putText(img=output_image_frame, text=text_draw,
|
|
# # org=draw_text_postion,
|
|
# # fontFace=font_draw_number,
|
|
# # fontScale=0.8, color=(9,10, 240), thickness=2)
|
|
# row+=1
|
|
|
|
# return output_image_frame
|
|
# 添加抬头半透明框
|
|
def addtitlerectangle(im0):
|
|
# im0= cv2.resize(im0,(1920,1080))
|
|
blk = np.zeros(im0.shape, np.uint8)
|
|
|
|
cv2.rectangle(blk,(0, 0), (400, 200), (255, 255, 255), -1) # 注意在 blk的基础上进行绘制;
|
|
# output_image_frame = cv2.addWeighted(output_image_frame, 1.0, blk, 0.5, 1)
|
|
alpha = 1
|
|
# beta 为第二张图片的透明度
|
|
beta = 0.5
|
|
gamma = 0
|
|
# cv2.addWeighted 将原始图片与 mask 融合
|
|
im0 = cv2.addWeighted(im0, alpha, blk, beta, gamma)
|
|
return im0
|
|
|
|
# def addcolorimg(im0):
|
|
# # im0= cv2.resize(im0,(1920,1080))
|
|
# im0 = cv2.add(im0, color_polygons_image)
|
|
# return im0
|
|
|
|
def addcolorimg(im0):
|
|
alpha = 1
|
|
# beta 为第二张图片的透明度
|
|
beta = 0.5
|
|
gamma = 0
|
|
# cv2.addWeighted 将原始图片与 mask 融合
|
|
im0 = cv2.addWeighted(im0, alpha, color_polygons_image, beta, gamma)
|
|
|
|
return im0
|
|
|
|
def addcount(list_bboxs,img):
|
|
if len(list_bboxs) == 0:
|
|
# 如果图像中没有任何的bbox,则清空list
|
|
list_overlapping_blue_polygon.clear()
|
|
list_overlapping_yellow_polygon.clear()
|
|
return
|
|
# ----------------------判断撞线----------------------
|
|
for item_bbox in list_bboxs:
|
|
x1, y1, x2, y2, track_id,cls_id= item_bbox
|
|
|
|
|
|
# 撞线检测点,(x1,y1),y方向偏移比例 0.0~1.0
|
|
y1_offset = int(y1 + ((y2 - y1) * 0.6))
|
|
|
|
# 撞线的点
|
|
y = y1_offset
|
|
x = int((x1+x2)*0.5)
|
|
|
|
if polygon_mask_blue_and_yellow[y, x] == 1:
|
|
# 如果撞 蓝polygon
|
|
if track_id not in list_overlapping_blue_polygon:
|
|
list_overlapping_blue_polygon.append(track_id)
|
|
print('\033[34m')
|
|
print("蓝色列表=",list_overlapping_blue_polygon)
|
|
print(f'进入蓝色区域cls_id ={cls_id} track_id=' +str(track_id) )
|
|
pass
|
|
|
|
# 判断 黄polygon list 里是否有此 track_id
|
|
# 有此 track_id,则 认为是 外出方向
|
|
if track_id in list_overlapping_yellow_polygon:
|
|
# 外出+1
|
|
# up_count += 1
|
|
countmodel= addcountup(cls_id)
|
|
label=clsnames[cls_id]
|
|
print(f'类别: {label} | id: {track_id} | 上行撞线 | 上行撞线总数: {countmodel["up"]} | 上行id列表: {list_overlapping_yellow_polygon}')
|
|
# 删除 黄polygon list 中的此id
|
|
list_overlapping_yellow_polygon.remove(track_id)
|
|
ec.warningunit.filter(item_bbox,list_bboxs,1,img.shape)
|
|
filename=f'out/up_{cls_id}_{track_id}.jpg'
|
|
cv2.imwrite(filename,img)
|
|
|
|
pass
|
|
else:
|
|
# 无此 track_id,不做其他操作
|
|
pass
|
|
|
|
elif polygon_mask_blue_and_yellow[y, x] == 2:
|
|
# 如果撞 黄polygon
|
|
if track_id not in list_overlapping_yellow_polygon:
|
|
list_overlapping_yellow_polygon.append(track_id)
|
|
print('\033[33m')
|
|
print("黄色列表=",list_overlapping_yellow_polygon)
|
|
print(f'进入黄色区域 cls_id ={cls_id} track_id=' +str(track_id) )
|
|
pass
|
|
|
|
# 判断 蓝polygon list 里是否有此 track_id
|
|
# 有此 track_id,则 认为是 进入方向
|
|
if track_id in list_overlapping_blue_polygon:
|
|
# 进入+1
|
|
# down_count += 1
|
|
countmodel= addcountdown(cls_id)
|
|
label=clsnames[cls_id]
|
|
print(f'类别: {label} | id: {track_id} | 下行撞线 | 下行撞线总数: {countmodel["down"]} | 下行id列表: {list_overlapping_blue_polygon}')
|
|
|
|
# 删除 蓝polygon list 中的此id
|
|
list_overlapping_blue_polygon.remove(track_id)
|
|
ec.warningunit.filter(item_bbox,list_bboxs,2,img.shape)
|
|
filename=f'out/down_{cls_id}_{track_id}.jpg'
|
|
cv2.imwrite(filename,img)
|
|
pass
|
|
else:
|
|
# 无此 track_id,不做其他操作
|
|
pass
|
|
pass
|
|
else:
|
|
pass
|
|
pass
|
|
|
|
pass
|
|
|
|
# ----------------------清除无用id----------------------
|
|
list_overlapping_all = list_overlapping_yellow_polygon + list_overlapping_blue_polygon
|
|
for id1 in list_overlapping_all:
|
|
is_found = False
|
|
for _, _, _, _, bbox_id,_ in list_bboxs:
|
|
if bbox_id == id1:
|
|
is_found = True
|
|
break
|
|
pass
|
|
pass
|
|
|
|
if not is_found:
|
|
# 如果没找到,删除id
|
|
if id1 in list_overlapping_yellow_polygon:
|
|
list_overlapping_yellow_polygon.remove(id1)
|
|
pass
|
|
if id1 in list_overlapping_blue_polygon:
|
|
list_overlapping_blue_polygon.remove(id1)
|
|
|
|
pass
|
|
print('delete id1='+str(id1))
|
|
pass
|
|
list_overlapping_all.clear()
|
|
pass
|
|
|
|
# 清空list
|
|
# list_bboxs.clear()
|
|
|
|
|
|
|
|
|