import argparse
from glob import glob
import time
from pathlib import Path
import os
from unicodedata import name
import cv2
from cv2.gapi import copy
import torch
import torch.backends.cudnn as cudnn
from numpy import random
import torch.nn.functional as F

from models.experimental import attempt_load
from utils.datasets import LoadStreams, LoadImages
from utils.general import check_img_size, check_requirements, check_imshow, non_max_suppression, apply_classifier, \
    scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path
from utils.plots import plot_one_box
from utils.torch_utils import select_device, load_classifier, time_synchronized
import numpy as np
import math
from tqdm import tqdm
#   uint8_t color[14][3]={{0,0,0},{255,0,0},{0,255,0},{0,0,255},{255,255,0},     // 0背景,1车道线,2停车位线,3禁止停车,4斑马线
#                        {255,0,255},{0,255,255},{127,0,0},{0,127,0},{0,0,127}, // 5人行横道预告标志线,6减速带,7指示直行,8坡道导流线,9轮挡,
#                        {127,127,0},{127,0,127},{0,127,127},{255,127,127},};   // 10车位角点,11停止线,12立柱,13路沿
Cityscapes_COLORMAP = [
    # [128, 64, 128],
    [0,0,0],          # 0背景
    [244, 35, 232],   # 1车道线
    [0, 0, 192],      # 2停车位线
    [70, 70, 70],     # 3禁止停车
    [102, 102, 0],    # 4斑马线
    [190, 153, 153],  # 5人行横道预告标志线
    [255, 255, 255],  # 6减速带
    [250, 170, 30],   # 7指示直行
    [220, 220, 0],    # 8坡道导流线
    [255, 0, 0],      # 9轮挡
    [152, 251, 152],  # 10车位角点
    [0, 130, 180],    # 11停止线
    [220, 0, 220],    # 12立柱
    [0, 255, 0],      # 13路沿
    # [0, 0, 0],
    [0, 0, 70],
    [0, 60, 100],
    [0, 80, 100],
    [0, 0, 230],
    [119, 11, 32],
]

Cityscapes_IDMAP = [
    [7],
    [8],
    [11],
    [12],
    [13],
    [17],
    [19],
    [20],
    [21],
    [22],
    [23],
    [24],
    [25],
    [26],
    [27],
    [28],
    [31],
    [32],
    [33],
]

Cityscapes_Class = ["road", "sidewalk", "building", "wall", "fence",
               "pole", "traffic light", "traffic sign", "vegetation",
               "terrain", "sky", "person", "rider", "car", "truck",
               "bus", "train", "motorcycle", "bicyle"]

def calculate_area(rect1):
    x1, y1, x2, y2, x3, y3, x4, y4 = rect1["pointx"][0],rect1["pointy"][0],rect1["pointx"][1],rect1["pointy"][1],rect1["pointx"][2],rect1["pointy"][2],rect1["pointx"][3],rect1["pointy"][3]
    # 计算四边形的四条边的长度
    a = math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
    b = math.sqrt((x2 - x3)**2 + (y2 - y3)**2)
    c = math.sqrt((x3 - x4)**2 + (y3 - y4)**2)
    d = math.sqrt((x4 - x1)**2 + (y4 - y1)**2)
    # 计算半周长
    p = (a + b + c + d) / 2
    # 应用海龙公式计算四边形面积
    area = math.sqrt((p - a) * (p - b) * (p - c) * (p - d))
    return area

def overlap_area(rect1, rect2):
    # 分别获取两个四边形的四个顶点坐标
    ax1, ay1, ax2, ay2, ax3, ay3, ax4, ay4 = rect1["pointx"][0],rect1["pointy"][0],rect1["pointx"][1],rect1["pointy"][1],rect1["pointx"][2],rect1["pointy"][2],rect1["pointx"][3],rect1["pointy"][3]
    bx1, by1, bx2, by2, bx3, by3, bx4, by4 = rect2["pointx"][0],rect2["pointy"][0],rect2["pointx"][1],rect2["pointy"][1],rect2["pointx"][2],rect2["pointy"][2],rect2["pointx"][3],rect2["pointy"][3]

    # 分别计算两个四边形在x轴和y轴上的投影长度
    acx_min, acx_max = min(ax1, ax2, ax3, ax4), max(ax1, ax2, ax3, ax4)
    bcx_min, bcx_max = min(bx1, bx2, bx3, bx4), max(bx1, bx2, bx3, bx4)
    acy_min, acy_max = min(ay1, ay2, ay3, ay4), max(ay1, ay2, ay3, ay4)
    bcy_min, bcy_max = min(by1, by2, by3, by4), max(by1, by2, by3, by4)

    # 判断两个四边形是否有重叠部分,如果没有则返回0
    if (acx_min > bcx_max or acx_max < bcx_min or 
        acy_min > bcy_max or acy_max < bcy_min):
        return 0

    # 计算两个四边形重叠部分的顶点坐标
    overlap_vertices = []
    for x in [acx_min, acx_max]:
        for y in [acy_min, acy_max]:
            if is_inside_rect(x, y, rect1) and is_inside_rect(x, y, rect2):
                overlap_vertices.append((x, y))

    # 如果重叠部分有4个或更多顶点,则表示它们之间有交集
    if len(overlap_vertices) >= 4:
        # 计算重叠部分的面积
        overlap_area = convex_polygon_area(overlap_vertices)
        return overlap_area
    else:
        return 0

def is_inside_rect(x, y, rect):
    ax1, ay1, ax2, ay2, ax3, ay3, ax4, ay4 = rect
    # 判断点(x, y)是否在以(ax1, ay1), (ax2, ay2), (ax3, ay3), (ax4, ay4)为顶点的四边形内部
    cross_product = (ax2 - ax1)*(y - ay1) - (ay2 - ay1)*(x - ax1)
    is_left = cross_product > 0
    for i in range(2, 5):
        ax, ay = rect[2*i], rect[2*i+1]
        cross_product = (ax - ax[i-1])*(y - ay[i-1]) - (ay - ay[i-1])*(x - ax[i-1])
        if (cross_product > 0) != is_left:
            return False
    return True

def convex_polygon_area(vertices):
    n = len(vertices)
    area = 0
    for i in range(n):
        x1, y1 = vertices[i]
        x2, y2 = vertices[(i+1)%n]
        area += x1*y2 - x2*y1
    return abs(area) / 2

def scale_coords_landmarks(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, 4, 6]] -= pad[0]  # x padding
    coords[:, [1, 3, 5, 7]] -= pad[1]  # y padding
    coords[:, :8] /= gain
    #clip_coords(coords, img0_shape)
    coords[:, 0].clamp_(0, img0_shape[1])  # x1
    coords[:, 1].clamp_(0, img0_shape[0])  # y1
    coords[:, 2].clamp_(0, img0_shape[1])  # x2
    coords[:, 3].clamp_(0, img0_shape[0])  # y2
    coords[:, 4].clamp_(0, img0_shape[1])  # x3
    coords[:, 5].clamp_(0, img0_shape[0])  # y3
    coords[:, 6].clamp_(0, img0_shape[1])  # x4
    coords[:, 7].clamp_(0, img0_shape[0])  # y4
    # coords[:, 8].clamp_(0, img0_shape[1])  # x5
    # coords[:, 9].clamp_(0, img0_shape[0])  # y5
    return coords

def label2image(pred, COLORMAP=Cityscapes_COLORMAP):
    colormap = np.array(COLORMAP, dtype='uint8')
    X = pred.astype('int32')
    return colormap[X, :]

def trainid2id(pred, IDMAP=Cityscapes_IDMAP):
    colormap = np.array(IDMAP, dtype='uint8')
    X = pred.astype('int32')
    return colormap[X, :]

def detect(save_img=True):
    source, weights, view_img, save_txt, imgsz = opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
    save_img = not opt.nosave and not source.endswith('.txt')  # save inference images
    webcam = source.isnumeric() or source.endswith('.txt') or source.lower().startswith(
        ('rtsp://', 'rtmp://', 'http://', 'https://'))

    # Directories
    save_dir = Path(increment_path(Path(opt.project) / opt.name, exist_ok=opt.exist_ok))  # increment run
    videoname = source.split("/")[-1][:-4]
    savepath_video = source.replace(source.split("/")[-1],"")
    save_rm = opt.source + "/rm/"
    save_fsd = opt.source + "/fsd/"
    save_e2e = opt.source[:-4] + "/e2e/"
    (save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir
    if opt.submit:
        sub_dir = str(save_dir) + "/results/"
        if not os.path.exists(sub_dir):
            os.mkdir(sub_dir)
    # if not os.path.exists(save_rm):
    #     os.mkdir(save_rm)
    #     # os.mkdir(save_rm_mask)
    #     os.mkdir(save_fsd)
    #     os.mkdir(save_e2e)
    #     # os.mkdir(save_fsd_mask) 

    # Initialize
    set_logging()
    device = select_device(opt.device)
    half = device.type != 'cpu'  # half precision only supported on CUDA 原始代码,cpu用float32,gpu用float16
    # half = False  # 强制禁用float16推理, 20和30系列显卡有tensor cores float16, 10系列卡不开cudnn.benchmark速度反而降
    # Load model
    model = attempt_load(weights, map_location=device)  # load FP32 model
    stride = int(model.stride.max())  # model stride
    imgsz = check_img_size(imgsz, s=stride)  # check img_size
    if half:
        model.half()  # to FP16

    # Second-stage classifier
    classify = False
    if classify:
        modelc = load_classifier(name='resnet101', n=2)  # initialize
        modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']).to(device).eval()

    # Set Dataloader
    vid_path, vid_writer, s_writer = None, None, None
    if webcam:
        view_img = check_imshow()
        cudnn.benchmark = True  # set True to speed up constant image size inference
                                # 开启后第一次推理会把各种后端算法测试一遍,后续推理都用最快的算法,会有较明显加速
                                # 算法速度不仅与复杂度有关,也与输入规模相关,因此要求后续输入同尺寸,原版仅在视频测试时开启,想测真实速度应该开启
        dataset = LoadStreams(source, img_size=imgsz, stride=stride)
    else:
        cudnn.benchmark = False
        dataset = LoadImages(source, img_size=imgsz, stride=stride)  # 跑的是这个

    if opt.submit or opt.save_as_video:  # 提交和做视频必定是同尺寸
        cudnn.benchmark = True
        
    # Get names and colors
    names = model.module.names if hasattr(model, 'module') else model.names
    colors = [[random.randint(0, 255) for _ in range(3)] for _ in names]

    # Run inference
    if device.type != 'cpu':
        model(torch.zeros(1, 3, imgsz, imgsz).to(device).type_as(next(model.parameters())))  # run once
    t0 = time.time()
    zh = -1
    for path, img, im0s, vid_cap in dataset:
        zh += 1
        if 10 > zh >= 0:
            pathzh = "000" + str(zh)
        if 100 > zh >= 10:
            pathzh = "00" + str(zh)
        if 1000 > zh >= 100:
            pathzh = "0" + str(zh)
        if zh >= 1000:
            pathzh = str(zh)
        imgname = path.split("/")[-1]
        img_zh = img.transpose(1,2,0)

        img = torch.from_numpy(img).to(device)
        
        img = img.half() if half else img.float()  # uint8 to fp16/32
        img /= 255.0  # 0 - 255 to 0.0 - 1.0
        if img.ndimension() == 3:
            img = img.unsqueeze(0)

        # Inference
        with torch.no_grad():
            t1 = time_synchronized()
            out = model(img, augment=opt.augment)
            pred = out[0][0]
            seg = out[1][1]  # [0]
            seg_fsd = out[1][0]
            
        # Apply NMS
            opt.iou_thres = 0.45
            pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms)
            t2 = time_synchronized()

        # Apply Classifier
        if classify:
            pred = apply_classifier(pred, modelc, img, im0s)

        # Process detections
        for i, det in enumerate(pred):  # detections per image
            if webcam:  # batch_size >= 1
                p, s, im0, frame = path[i], '%g: ' % i, im0s[i].copy(), dataset.count
            else:
                p, s, im0, frame = path, '', im0s, getattr(dataset, 'frame', 0)
            im0_zh = im0s.copy()
            p = Path(p)  # to Path
            save_path = str(save_dir / p.name)  # img.jpg
            txt_path = str(save_dir / 'labels' / p.stem) + ('' if dataset.mode == 'image' else f'_{frame}')  # img.txt
            s += '%gx%g ' % img.shape[2:]  # print string
            gn = torch.tensor(im0.shape)[[1, 0, 1, 0]]  # normalization gain whwh
            if len(det):
                # Rescale boxes from img_size to im0 size
                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()

                # Print results
                for c in det[:, -1].unique():
                    n = (det[:, -1] == c).sum()  # detections per class
                    s += f"{n} {names[int(c)]}{'s' * (n > 1)}, "  # add to string
                
                #point
                det[:, 5:13] = scale_coords_landmarks(img.shape[2:], det[:, 5:13], im0.shape).round()
                #conf
                conf_all = det[:, 4]
                classindex = det[:, 13:14]
                solttype = det[:, 14:]

                # Write results
                for *xyxy, conf, cls in reversed(det):
                    if save_txt:  # Write to file
                        xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh
                        line = (cls, *xywh, conf) if opt.save_conf else (cls, *xywh)  # label format
                        with open(txt_path + '.txt', 'a') as f:
                            f.write(('%g ' * len(line)).rstrip() % line + '\n')

                    # if save_img or view_img:  # Add bbox to image
                    #     label = f'{names[int(cls)]} {conf:.2f}'
                    #     plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
                    if save_img or view_img:  # Add point to image  save_img or view_img
                        point = det[:, 5:13]
                        point_all =[]
                        for i in range(len(point)):
                            point_dict1={}
                            x1,y1 = int(point[i][0]),int(point[i][1])
                            x2,y2 = int(point[i][2]),int(point[i][3])
                            x3,y3 = int(point[i][4]),int(point[i][5])
                            x4,y4 = int(point[i][6]),int(point[i][7])
                            point_dict1["conf"] = conf_all[i]
                            point_dict1["isOccupied"] = solttype[i][0]
                            point_dict1["isVIP"] = solttype[i][1]
                            point_dict1["iswoman"] = solttype[i][2]
                            point_dict1["isdisabled"] = solttype[i][3]
                            point_dict1["ischarging"] = solttype[i][4]
                            point_dict1["step"] = solttype[i][5]
                            point_dict1["name"] = names[int(classindex[i])]
                            point_dict1["delrule"] = 0
                            point_dict1["pointx"] = [x1,x2,x3,x4]
                            point_dict1["pointy"] = [y1,y2,y3,y4]
                            point_all.append(point_dict1)
                        # #过滤规则1,重合度 如果入口点两个点相近低于40个像素 那么过滤置信度低的那个
                        sorted(point_all,key=lambda d: d["conf"])
                        end = len(point_all)
                        for i in range(len(point_all)):
                            if point_all[i]["delrule"] == 0:
                                for j in range(i+1,end):
                                    #简单就是求入口顶点之间的距离
                                    xi1 = point_all[i]['pointx'][0]
                                    yi1 = point_all[i]['pointy'][0]
                                    xi2 = point_all[i]['pointx'][1]
                                    yi2 = point_all[i]['pointy'][1]
                                    xj1 = point_all[j]['pointx'][0]
                                    yj1 = point_all[j]['pointy'][0]
                                    xj2 = point_all[j]['pointx'][1]
                                    yj2 = point_all[j]['pointy'][1]  
                                    if (abs(xi1 - xj1) + abs(yi1 - yj1)) < 40 or (abs(xi2 - xj2) + abs(yi2 - yj2)) < 40:
                                        point_all[j]["delrule"] = 1
                                #求面积是一种方法
                                # uare = overlap_area(point_all[i],point_all[j])
                                # if uare > 0:
                                #     minare = uare / min(calculate_area((point_all[i])),calculate_area((point_all[j])))
                                #     if minare > 0.5:
                                #         point_all[j]["delrule"] = 1
                        # #过滤规则2,  求两条分割线的平行度(角度)
                        for i in range(len(point_all)):
                            if point_all[i]["delrule"] == 0:
                                line1 = [point_all[i]['pointx'][0],point_all[i]['pointy'][0],point_all[i]['pointx'][3],point_all[i]['pointy'][3]]
                                line2 = [point_all[i]['pointx'][1],point_all[i]['pointy'][1],point_all[i]['pointx'][2],point_all[i]['pointy'][2]]
                                vec1 =[line1[2]-line1[0],line1[3]-line1[1]]
                                vec2 =[line2[2]-line2[0],line2[3]-line2[1]]
                                #计算向量的点积和模长
                                dot_product = vec1[0] * vec2[0] + vec1[1] * vec2[1]
                                m1 = math.sqrt(vec1[0]**2 + vec1[1]**2) + 0.000000000001
                                m2 = math.sqrt(vec2[0]**2 + vec2[1]**2) + 0.000000000001
                                
                                val = dot_product/(m1 * m2)
                                if val > 1:
                                    val = 1
                                if val < -1:
                                    val = -1
                                radians = math.acos(val)
                                du = math.degrees(radians)
                                if du > 20:
                                    point_all[i]["delrule"] = 2
                        # import copy
                        # im0e2e = copy.deepcopy(im0)
                        
                        if 1:
                            for point_i in point_all:
                                if point_i["delrule"] == 0:
                                    if point_i["conf"] > 0.45:
                                    # if point_i["conf"] > 0:
                                        cv2.putText(im0, f'{point_i["conf"]:.3f}', 
                                            (point_i["pointx"][0] + 6, point_i["pointy"][0] + 6),
                                            cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)   #置信度
                                        cv2.putText(im0, point_i["name"], 
                                            (point_i["pointx"][0] + 6, point_i["pointy"][0] + 30),
                                            cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #类别
                                        # if float(point_i["isOccupied"])> 0.5:
                                        if float(point_i["isOccupied"])> 0.1:
                                            cv2.putText(im0, "Occ :" + f'{point_i["isOccupied"]:.3f}', 
                                                (point_i["pointx"][0] + 6, point_i["pointy"][0] + 54),
                                                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #是否被占用
                                        if float(point_i["isVIP"]) > 0.5:
                                            cv2.putText(im0, "VIP :" + f'{point_i["isVIP"]:.3f}', 
                                                (point_i["pointx"][0] + 6, point_i["pointy"][0] + 78),
                                                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #是否VIP车位
                                        if float(point_i["iswoman"]) > 0.5:
                                            cv2.putText(im0, "woman :" + f'{point_i["iswoman"]:.3f}', 
                                                (point_i["pointx"][0] + 6, point_i["pointy"][0] + 102),
                                                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #是否女性车位
                                        if float(point_i["isdisabled"]) > 0.5:
                                            cv2.putText(im0, "disab :" + f'{point_i["isdisabled"]:.3f}', 
                                                (point_i["pointx"][0] + 6, point_i["pointy"][0] + 126),
                                                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #是否残疾人车位
                                        if float(point_i["ischarging"]) > 0.5:
                                            cv2.putText(im0, "charg :" + f'{point_i["ischarging"]:.3f}', 
                                                (point_i["pointx"][0] + 6, point_i["pointy"][0] + 150),
                                                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #是否充电车位
                                        if float(point_i["step"]) > 0.5:
                                            cv2.putText(im0, "step :" + f'{point_i["step"]:.3f}', 
                                                (point_i["pointx"][0] + 6, point_i["pointy"][0] + 174),
                                                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0),2)     #是否阶梯形车位
                                        cv2.arrowedLine(im0, (point_i["pointx"][0], point_i["pointy"][0]),(point_i["pointx"][1], point_i["pointy"][1]), (0, 255, 0),   1, cv2.LINE_AA)
                                        cv2.arrowedLine(im0, (point_i["pointx"][1], point_i["pointy"][1]),(point_i["pointx"][2], point_i["pointy"][2]), (255, 255, 0), 1, cv2.LINE_AA)
                                        cv2.arrowedLine(im0, (point_i["pointx"][2], point_i["pointy"][2]),(point_i["pointx"][3], point_i["pointy"][3]), (255, 255, 0), 1, cv2.LINE_AA)
                                        cv2.arrowedLine(im0, (point_i["pointx"][3], point_i["pointy"][3]),(point_i["pointx"][0], point_i["pointy"][0]), (255, 255, 0), 1, cv2.LINE_AA) 
                                    else:
                                        cv2.putText(im0, f'{point_i["conf"]:.3f}', 
                                            (point_i["pointx"][0] + 6, point_i["pointy"][0] + 6),
                                            cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255),3)      
                                        cv2.arrowedLine(im0, (point_i["pointx"][0], point_i["pointy"][0]),(point_i["pointx"][1], point_i["pointy"][1]), (0, 0, 255),   1, cv2.LINE_AA)
                                        cv2.arrowedLine(im0, (point_i["pointx"][1], point_i["pointy"][1]),(point_i["pointx"][2], point_i["pointy"][2]), (0, 0, 255), 1, cv2.LINE_AA)
                                        cv2.arrowedLine(im0, (point_i["pointx"][2], point_i["pointy"][2]),(point_i["pointx"][3], point_i["pointy"][3]), (0, 0, 255), 1, cv2.LINE_AA)
                                        cv2.arrowedLine(im0, (point_i["pointx"][3], point_i["pointy"][3]),(point_i["pointx"][0], point_i["pointy"][0]), (0, 0, 255), 1, cv2.LINE_AA) 
                                if point_i["delrule"] == 1:
                                    cv2.putText(im0, f'{point_i["conf"]:.3f}', 
                                        (point_i["pointx"][0] + 6, point_i["pointy"][0] + 6),
                                        cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255),3)      
                                    cv2.arrowedLine(im0, (point_i["pointx"][0], point_i["pointy"][0]),(point_i["pointx"][1], point_i["pointy"][1]), (0, 0, 0), 1, cv2.LINE_AA)
                                    cv2.arrowedLine(im0, (point_i["pointx"][1], point_i["pointy"][1]),(point_i["pointx"][2], point_i["pointy"][2]), (0, 0, 0), 1, cv2.LINE_AA)
                                    cv2.arrowedLine(im0, (point_i["pointx"][2], point_i["pointy"][2]),(point_i["pointx"][3], point_i["pointy"][3]), (0, 0, 0), 1, cv2.LINE_AA)
                                    cv2.arrowedLine(im0, (point_i["pointx"][3], point_i["pointy"][3]),(point_i["pointx"][0], point_i["pointy"][0]), (0, 0, 0), 1, cv2.LINE_AA)
                                if point_i["delrule"] == 2:
                                    cv2.putText(im0, f'{point_i["conf"]:.3f}', 
                                        (point_i["pointx"][0] + 6, point_i["pointy"][0] + 6),
                                        cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255),3)      
                                    cv2.arrowedLine(im0, (point_i["pointx"][0], point_i["pointy"][0]),(point_i["pointx"][1], point_i["pointy"][1]), (0, 0, 0), 1, cv2.LINE_AA)
                                    cv2.arrowedLine(im0, (point_i["pointx"][1], point_i["pointy"][1]),(point_i["pointx"][2], point_i["pointy"][2]), (0, 0, 0), 1, cv2.LINE_AA)
                                    cv2.arrowedLine(im0, (point_i["pointx"][2], point_i["pointy"][2]),(point_i["pointx"][3], point_i["pointy"][3]), (0, 0, 0), 1, cv2.LINE_AA)
                                    cv2.arrowedLine(im0, (point_i["pointx"][3], point_i["pointy"][3]),(point_i["pointx"][0], point_i["pointy"][0]), (0, 0, 0), 1, cv2.LINE_AA)  

            # Print time (inference + NMS)
            print(f'{s}Done. ({t2 - t1:.5f}s)')
            # seg = seg[0]
            # seg = seg[:, :, :,11:404]
            seg = F.interpolate(seg, (im0.shape[0], im0.shape[1]), mode='bilinear', align_corners=True)[0] #im0.shape[1]
            mask = label2image(seg.max(axis=0)[1].cpu().numpy(), Cityscapes_COLORMAP)[:, :, ::-1]
            dst = cv2.addWeighted(mask, 0.5, im0_zh, 0.7, 0)
            outmask = seg.max(axis=0)[1].cpu().numpy()
            # a, b = np.unique(outmask, return_counts=True)
            #fsd 输出
            aaa = seg_fsd.max(axis=0)[1].cpu().numpy()
            seg_fsd = F.interpolate(seg_fsd, (im0.shape[0], im0.shape[1]), mode='bilinear', align_corners=True)[0] #im0.shape[1]
            mask_fsd = label2image(seg_fsd.max(axis=0)[1].cpu().numpy(), Cityscapes_COLORMAP)[:, :, ::-1]
            dst_fsd = cv2.addWeighted(mask_fsd, 0.3, im0, 0.7, 0)
            outmask_fsd = seg_fsd.max(axis=0)[1].cpu().numpy()

            # Save results (image with detections)
            if save_img:
                #暂时
                cv2.imwrite('/home02/ypli/video/rm/' + "rm_" + pathzh + ".png" , mask)
                # cv2.imwrite(save_fsd + imgname , dst_fsd)
                imzh = cv2.hconcat([dst,dst_fsd])
                # cv2.imwrite(save_e2e + imgname[:-4] + '.jpg' , imzh)
                
            #     if dataset.mode == 'image':
            #         cv2.imwrite(save_path, im0)
            #         cv2.imwrite(save_path[:-4]+"_mask"+save_path[-4:], mask)
            #         cv2.imwrite(save_path[:-4]+"_dst"+save_path[-4:], dst)
            #     else: # 'video' or 'stream'
            #         if vid_path != save_path:  # new video
            #             vid_path = save_path
            #             if isinstance(vid_writer, cv2.VideoWriter):
            #                 vid_writer.release()  # release previous video writer
            #             if vid_cap:  # video
            #                 fps = vid_cap.get(cv2.CAP_PROP_FPS)
            #                 w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            #                 h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            #             else:  # stream
            #                 fps, w, h = 25, dst.shape[1], dst.shape[0]
            #                 save_path += '.mp4'
            #             vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
            #         vid_writer.write(dst)#(im0)
                if 1:
                    if not s_writer:
                        fps, w, h = 25, imzh.shape[1], imzh.shape[0]
                        s_writer = cv2.VideoWriter(str(savepath_video) + videoname +"1211_out.mp4", cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
                    s_writer.write(imzh)
    if save_txt or save_img:
        s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ''
        print(f"Results saved to {save_dir}{s}")
    if s_writer != None:
        s_writer.release()
    print(f'Done. ({time.time() - t0:.3f}s)')
 

if __name__ == '__main__': 
    parser = argparse.ArgumentParser()
    #\\10.2.2.80\hzhang\data\video\EC31-TDA4 技术中心大楼东 小型T型车位晴天傍晚采图DVR-11.6-杨韦康\EC31-TDA4 技术中心大楼东 小型T型车位晴天傍晚采图DVR\plr\20231106
    # runs/train/exp48/weights/exp52_last_115_20250311_v2.0.25.pt  #zh
    # runs/train/exp48/weights/exp52_last_115_20250319_v2.0.26.pt
    # runs/train/exp54/weights/exp55_last_104_20250430_v2.0.27.pt
    # runs/train/exp54/weights/exp54_last_118_20250530_v2.0.28.pt
    # runs/train/exp54/weights/exp54_last_118_20250607_v2.0.29.pt
    # runs/train/exp54/weights/exp54_last_118_20250619_v2.0.30.pt
    # runs/train/exp54/weights/exp54_last_118_20250714_v2.0.31.pt
    # runs/train/exp54/weights/exp54_last_114_20250731_v2.0.32.pt
    # runs/train/exp54/weights/exp54_last_118_20250812_v2.0.33.pt
    # runs/train/exp54/weights/exp54_last_115_20250912_v2.0.34.pt
    # runs/train/exp54/weights/exp54_last_116_20250917_v2.0.35.pt
    # runs/train/exp54/weights/exp54_last_118_20251013_v2.0.36.pt
    # runs/train/exp54/weights/exp54_last_116_20251016_v2.0.37.pt
    #parser.add_argument('--weights', nargs='+', type=str, default="/home02/ypli/infer_Multask_rm_v2/runs/train/v44_last_117.pt", help='model.pt path(s)') 
    parser.add_argument('--weights', nargs='+', type=str, default="/home02/ypli/infer_Multask_rm_v2/runs/train/exp54/weights/v2038_last_125_20260204.pt", help='model.pt path(s)') 
   # parser.add_argument('--weights', nargs='+', type=str, default="runs/train/exp54/weights/exp54_last_116_20251016_v2.0.37.pt", help='model.pt path(s)') 
    #exp51_last_111_v2.0.13_0819   exp51_last_111_0826 exp51_last_106_0902
    # /Common2/roadmarking/annotation/ks/share/占用属性测试数据/1/P03侵占车位识别阈值测试场景1垂直车位7.26/侵占40cm
    parser.add_argument('--source', type=str, default='/10.2.101.76_share/004_俯视图多任务模型问题场景分析/ppchen/00_融合规控Gen2.0/WI-4384_车位入口小台阶fsd和路沿误检/', help='source')  # file/folder, 0 for webcam 20240706105042
    parser.add_argument('--img-size', type=int, default=544, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.20, help='object confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='display results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default='runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--save-as-video',  default=False,action='store_true', help='save same size images as a video')
    parser.add_argument('--submit', action='store_true', help='get submit file in folder submit')
    opt = parser.parse_args()
    print(opt)
    check_requirements(exclude=('pycocotools', 'thop'))
    def find_zip_files(folder_path):
        zip_files = []
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                if file.endswith('.mp4'):
                    zip_files.append(os.path.join(root, file))
                if file.endswith('.avi'):
                    zip_files.append(os.path.join(root, file))
        return zip_files
    
    with torch.no_grad():
        if opt.update:  # update all models (to fix SourceChangeWarning)
            for opt.weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']:
                detect()
                strip_optimizer(opt.weights)
        else:
            source_1 = find_zip_files(opt.source)
            for i in tqdm(source_1):
                name = i.split('/')[-1]
                if os.path.exists(i.replace(name,name.split('.')[0]+'1211_out.' + name.split('.')[1])):
                    continue
                if "out." in i:
                    continue
                if "/test/" in i:
                    continue
                opt.source = i
                detect()
 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐