Beispiel #1
0
    def __init__(self, file_json, path_img, mode, transform=None, is_mosaic=False,
                 is_mosaic_keep_wh=False, is_mosaic_fill=False, is_debug=False, cfg=None,
                 s_ids_cats=None, nums_cat=None,
                 is_img_np=True, is_boxesone=True):
        '''

        :param file_json:
        :param path_img:
        :param mode:
        :param transform: 这个需与 is_img_np 配对使用
        :param is_mosaic:
        :param is_mosaic_keep_wh:
        :param is_mosaic_fill:
        :param is_debug:
        :param cfg:
        :param s_ids_cats:
        :param nums_cat:  每一个分类的最大图片数量
        :param is_img_np: 为Ture img_np 为False 为pil  这个需与 transform 配对使用
        :param is_boxesone: 归一化gt 尺寸
        '''
        self.file_json = file_json
        self.transform = transform
        self.mode = mode
        self.coco_obj = COCO(file_json)
        if s_ids_cats is not None:
            flog.warning('指定coco类型 %s', coco.loadCats(s_ids_cats))
            self.s_ids_cats = s_ids_cats
            ids_img = []

            # 限制每类的最大个数
            if nums_cat is None:
                for idc in zip(s_ids_cats):
                    # 类型对应哪些文件 可能是一张图片多个类型
                    ids_ = self.coco_obj.getImgIds(catIds=idc)
                    ids_img += ids_
            else:
                # 限制每类的最大个数
                for idc, num_cat in zip(s_ids_cats, nums_cat):
                    # 类型对应哪些文件 可能是一张图片多个类型
                    ids_ = self.coco_obj.getImgIds(catIds=idc)[:num_cat]
                    # ids_ = self.coco.getImgIds(catIds=idc)[:1000]
                    ids_img += ids_
                    # print(ids_)  # 这个只支持单个元素

            self.ids_img = list(set(ids_img))  # 去重
        else:
            self.ids_img = self.coco_obj.getImgIds()  # 所有图片的id 画图数量

        #  self.classes_ids self.classes_ids
        self._init_load_classes()  # 除了coco数据集,其它不管

        self.is_debug = is_debug
        self.is_mosaic = is_mosaic
        self.cfg = cfg
        self.path_img = path_img
        self.is_mosaic_keep_wh = is_mosaic_keep_wh
        self.is_mosaic_fill = is_mosaic_fill
        self.is_img_np = is_img_np  # img_np False 是img_pil
        if not os.path.exists(path_img):
            raise Exception('coco path_img 路径不存在', path_img)
Beispiel #2
0
def init_od_e(cfg, seed=0):
    # -----------通用系统配置----------------
    torch.set_printoptions(linewidth=320,
                           sci_mode=False,
                           precision=5,
                           profile='long')
    np.set_printoptions(linewidth=320,
                        suppress=True,
                        formatter={'float_kind': '{:11.5g}'.format
                                   })  # format short g, %precision=5
    matplotlib.rc('font', **{'size': 11})

    # 防止OpenCV进入多线程(使用PyTorch DataLoader)
    cv2.setNumThreads(0)

    # 随机种子
    torch.manual_seed(seed)
    np.random.seed(seed)
    torch.cuda.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    random.seed(seed)
    np.random.seed(seed)
    # from yolo5 Speed-reproducibility tradeoff https://pytorch.org/docs/stable/notes/randomness.html
    torch.manual_seed(seed)
    if seed == 0:  # slower, more reproducible
        cudnn.benchmark, cudnn.deterministic = False, True
    else:  # faster, less reproducible
        cudnn.benchmark, cudnn.deterministic = True, False

    if cfg.IS_MULTI_SCALE:
        cfg.tcfg_size = [640, 640]
        flog.warning("多尺度训练 ------ 开 最大 %s" % cfg.tcfg_size)
    else:
        cfg.tcfg_size = cfg.IMAGE_SIZE
        flog.warning("多尺度训练 ------ 关 %s", cfg.IMAGE_SIZE)
Beispiel #3
0
def model_out4one(model,
                  img_np,
                  data_transform,
                  size_ts,
                  labels_lsit,
                  target=None,
                  is_keeep=False):
    img_ts_one, boxes, labels = data_transform(img_np)
    img_ts4 = img_ts_one.unsqueeze_(0)
    '''---------------预测开始--------------'''
    ids_batch, p_boxes_ltrb, p_keypoints, p_labels, p_scores = model(img_ts4)
    size_input = size_ts
    if is_keeep:
        max1 = max(size_ts)
        size_input = torch.tensor([max1, max1])

    # 用于恢复bbox及ke
    szie_scale4bbox = size_input.repeat(2)

    if p_labels is None or len(p_labels) == 0:
        _text = '未检测出来,id为:%s'
        if target is not None:
            _text = _text % target['image_id']
        flog.warning(_text)
        plabels_text = None
        p_scores_float = None
        p_boxes_ltrb = p_boxes_ltrb
    else:
        plabels_text = []
        p_scores_float = []
        for i, label in enumerate(p_labels):
            plabels_text.append(labels_lsit[int(label.item())])
            p_scores_float.append(p_scores[i].item())
        p_boxes_ltrb = p_boxes_ltrb * szie_scale4bbox
    return p_boxes_ltrb, p_scores_float, plabels_text
Beispiel #4
0
def spilt_data2folder(path_root, val_rate=0.3):
    names_class = [cla for cla in os.listdir(path_root) if ".txt" not in cla]
    path_train_root = os.path.join(os.path.dirname(path_root), 'train')
    path_val_root = os.path.join(os.path.dirname(path_root), 'val')
    for n in names_class:
        path_train_n = os.path.join(path_train_root, n)
        path_val_n = os.path.join(path_val_root, n)

        if not os.path.exists(path_train_n):
            os.makedirs(path_train_n)
        else:
            flog.warning('文件夹已存在 %s', path_train_n)
            exit(-1)
        if not os.path.exists(path_val_n):
            os.makedirs(path_val_n)
        else:
            flog.warning('文件夹已存在 %s', path_val_n)
            exit(-1)

        path_cla_imgs = os.path.join(path_root, n)
        name_images = os.listdir(path_cla_imgs)
        num = len(name_images)
        eval_index = random.sample(name_images, k=int(num * val_rate))

        for i, n in tqdm(enumerate(name_images)):
            path_img = os.path.join(path_cla_imgs, n)
            if n in eval_index:  # 验值集
                path_img_new = os.path.join(path_val_n, n)
            else:
                path_img_new = os.path.join(path_train_n, n)
            copy(path_img, path_img_new)
            print("\r[{}] processing [{}/{}]".format(n, i + 1, num),
                  end="")  # processing bar

    print("spilt_data2folder done!")
Beispiel #5
0
    def handle_keypoints(self, coco_ann):
        '''

        :param coco_ann: 这里只会是一维标签
        :return:
        '''
        k_ = np.array(coco_ann['keypoints'])

        '''
        widerface 不需要加 mask
        这个是标注是否可用的的定义 
        # 如果关键点在物体segment内,则认为可见.
        # v=0 表示这个关键点没有标注(这种情况下x=y=v=0)
        # v=1 表示这个关键点标注了但是不可见(被遮挡了)
        # v=2 表示这个关键点标注了同时也可见
        '''
        inds = np.arange(2, len(k_), 3)  # 每隔两个选出 [ 2  5  8 11 14]
        mask = np.ones(len(coco_ann['keypoints']), dtype=np.float32)
        mask[inds] = 1
        _t = k_[inds] != 2
        if _t.any() and _t.sum() != len(_t):
            # 有 且 不是全部的进入
            _s = '标签不全为2 %s' % k_
            flog.error(_s)
            # raise Exception(_s)

        inds = np.arange(2, len(k_), 3)  # 每隔两个选出
        ones = np.ones(len(coco_ann['keypoints']), dtype=np.float32)
        ones[inds] = 0
        nonzero = np.nonzero(ones)  # 取非零索引
        keypoint_np = k_[nonzero]  # 选出10个数
        if np.all(keypoint_np == 0):
            flog.warning('出现全0 keypoints %s' % coco_ann)
            return None
        return keypoint_np
Beispiel #6
0
 def __call__(self, img, target):
     # f_plt_show_cv(image,boxes)
     for t in self.transforms:
         img, target = t(img, target)
         if target is not None:
             if len(target['boxes']) != len(target['labels']):
                 flog.warning('!!! 数据有问题 Compose  %s %s %s ',
                              len(target['boxes']), len(target['labels']),
                              t)
     return img, target
Beispiel #7
0
def fdatas_l2(batch_data, device, cfg, epoch, model):
    '''
    cpu转gpu 输入模型前数据处理方法 定制
    image = torch.nn.functional.interpolate(
            image[None], scale_factor=scale_factor,
            mode='bilinear', align_corners=False)[0]
    images = torch.nn.functional.interpolate(images, size=input_size, mode='bilinear', align_corners=False)
    :param batch_data:
    :param device:
    :return:
    '''
    images, targets = batch_data
    if model.training and cfg.IS_MULTI_SCALE:
        if epoch != cfg.tcfg_epoch and epoch % 10 == 0:
            # if epoch % 1 == 0:
            if fis_mgpu():
                randints = torch.randint(low=10,
                                         high=19,
                                         size=[1],
                                         device=device)
                dist.broadcast(randints, src=0)
                randint = randints[0].item()
            else:
                randint = random.randint(*cfg.MULTI_SCALE_VAL)

            cfg.tcfg_size = [randint * 32] * 2  # (320~608) 9个尺寸
            flog.warning("多尺度训练 epoch:{},尺度{}".format(epoch + 1,
                                                      cfg.tcfg_size))
            cfg.tcfg_epoch = epoch  # 避免重复判断

        images = torch.nn.functional.interpolate(images,
                                                 size=cfg.tcfg_size,
                                                 mode='bilinear',
                                                 align_corners=False)

    images = images.to(device)

    for target in targets:
        target['boxes'] = target['boxes'].to(device)
        target['labels'] = target['labels'].to(device)
        target['size'] = target['size'].to(device)
        if cfg.NUM_KEYPOINTS > 0:
            target['keypoints'] = target['keypoints'].to(device)

        # for key, val in target.items():
        #     target[key] = val.to(device)
    return images, targets
Beispiel #8
0
def f_show_coco_pics(coco, path_img, ids_img=None):
    '''
    遍历所有图片打开查看
    :param coco:
    :param path_img:
    :return:
    '''

    # id = 1
    # imgIds = coco.getImgIds(imgIds=[id])
    if not ids_img:
        ids = coco.getImgIds()
    else:
        ids = ids_img
    for id in ids:
        img_info = coco.loadImgs([id])  # 这里原始返回list
        # 本地加载 h,w,c
        # img = io.imread(os.path.join(path_img, img_info[0]['file_name']))
        file = os.path.join(path_img, img_info[0]['file_name'])
        if not os.path.exists(file):
            raise Exception('path不存在%s' % file)

        img = cv2.imread(file)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # flog.debug('imgsize %s', img.shape[:2][::-1])
        # 加载图片基本信息 h w id filename
        # 获取该图片的所有标注的id
        annIds = coco.getAnnIds(imgIds=img_info[0]['id'])
        anns = coco.loadAnns(annIds)  # annotation 对象

        # img_pil = f_open_cocoimg(path_img, coco, id)
        # for ann in anns:
        #     box_ltwh = np.array(ann['bbox'])[None]
        #     print(box_ltwh)  # ltwh
        #     box_ltrb = ltwh2ltrb(box_ltwh)
        #     show_anc4pil(img_pil, box_ltrb)

        flog.warning('宽高:%s x %s' % (img.shape[1], img.shape[0]))
        plt.axis('off')
        plt.imshow(img)
        coco.showAnns(anns)  # 显示标注
        plt.show()
Beispiel #9
0
def cre_transform_base4np(cfg):
    flog.warning('预处理使用 cre_transform_base4np', )
    data_transform = {
        "train":
        Compose([
            Resize(cfg.IMAGE_SIZE),
            Normalize(cfg.PIC_MEAN, cfg.PIC_STD),
            ConvertColor(current='BGR', transform='RGB'),
            ToTensor(is_box_oned=True),
        ], cfg)
    }

    data_transform["val"] = Compose([
        Resize(cfg.IMAGE_SIZE),
        Normalize(cfg.PIC_MEAN, cfg.PIC_STD),
        ConvertColor(current='BGR', transform='RGB'),
        ToTensor(is_box_oned=False),
    ], cfg)

    return data_transform
Beispiel #10
0
    def __init__(self, backbone, cfg):
        super(YOLOv1, self).__init__()
        if cfg.MODE_TRAIN == 1 or cfg.MODE_TRAIN == 4:  # base 或 IOU 损失及预测
            flog.warning('-------------- LossYOLOv1 ------------- %s', )
            self.net = YOLOv1_Net(backbone, cfg, cfg.NUM_CLASSES + 1)  # 带conf
            self.losser = LossYOLOv1(cfg=cfg)
            self.preder = PredictYOLOv1(cfg=cfg)

        elif cfg.MODE_TRAIN == 2:  # 去conf 只有cls reg分支
            flog.warning('-------------- LossYOLOv1_cr ------------- %s', )
            self.net = YOLOv1_Net(backbone, cfg,
                                  cfg.NUM_CLASSES)  # 只有cls及reg分支
            self.losser = LossYOLOv1_cr(cfg=cfg)
            self.preder = PredictYOLOv1_cr(cfg=cfg)

        elif cfg.MODE_TRAIN == 3:  # 任意分布 高级reg算法 暂时无效?
            self.net = YOLOv1_Net(backbone,
                                  cfg,
                                  cfg.NUM_CLASSES,
                                  num_reg=4 * cfg.NUM_REG)  # YOLOv1_Net
            self.losser = LossYOLOv1_cr(cfg=cfg)
            self.preder = PredictYOLOv1_cr(cfg=cfg)
Beispiel #11
0
def base_set_1gpu(cfg, id_gpu=0):
    # cfg.SAVE_FILE_NAME = os.path.basename(__file__)
    if torch.cuda.is_available():
        device = torch.device('cuda:%s' % id_gpu)
    else:
        device = torch.device("cpu")
        cfg.IS_MIXTURE_FIX = False
    flog.info('模型当前设备 %s', device)
    cfg.device = device  # cfg添加属性

    if cfg.DEBUG:
        flog.warning('debug模式')
        # device = torch.device("cpu")
        cfg.PRINT_FREQ = 1
        # cfg.PATH_SAVE_WEIGHT = None
        cfg.BATCH_SIZE = 5
        cfg.DATA_NUM_WORKERS = 0
        pass
    else:
        torch.multiprocessing.set_sharing_strategy('file_system')  # 多进程开文件

    return device, cfg
Beispiel #12
0
    def __getitem__(self, index):
        '''

        :param index:
        :return: tensor or np.array 根据 out: 默认ts or other is np
            img: h,w,c
            target:
            coco原装是 ltwh
            dict{
                image_id: int,
                bboxs: ts n4 原图 ltwh -> ltrb
                labels: ts n,
                keypoints: ts n,10
                size: wh
            }
        '''
        # 这里生成的是原图尺寸的 target 和img_np_uint8 (375, 500, 3)
        if self.is_mosaic and self.mode == 'bbox':
            res = self.do_mosaic(index)
        else:
            res = self.open_img_tar(index)

        if res is None:
            flog.error('这个图片没有标注信息 id为%s', index)
            return self.__getitem__(index + 1)

        img, target = res

        if len(target['boxes']) != len(target['labels']):
            flog.warning('!!! 数据有问题 1111  %s %s %s ', target, len(target['boxes']), len(target['labels']))

        '''---------------cocoAPI测试 查看图片在归一化前------------------'''
        # 这个用于调试
        # if self.cfg.IS_VISUAL_PRETREATMENT:
        #     可视化参数 is_mosaic 这个用不起
        #     f_show_coco_pics(self.coco_obj, self.path_img, ids_img=[index])

        if target['boxes'].shape[0] == 0:
            flog.warning('数据有问题 重新加载 %s', index)
            return self.__getitem__(index + 1)

        if self.transform is not None:
            img, target = self.transform(img, target)
            # if self.is_img_np:
            #     # 输入 ltrb 原图
            #     # f_plt_show_cv(img, gboxes_ltrb=target['boxes'])
            #     # img, boxes, labels = self.transform(img, target['boxes'], target['labels'])
            #     img, target = self.transform(img, target)
            #     # 这里会刷新 boxes, labels
            #     # f_plt_show_cv(img, gboxes_ltrb=boxes)
            # else:
            #     # 预处理输入 PIL img 和 np的target
            #     img, target = self.transform(img, target)

        if len(target['boxes']) != len(target['labels']):
            flog.warning('!!! 数据有问题 ttttttttt  %s %s %s ', target, len(target['boxes']), len(target['labels']))

        # target['boxes'] = torch.tensor(target['boxes'], dtype=torch.float)
        # target['labels'] = torch.tensor(target['labels'], dtype=torch.int64)
        target['size'] = torch.tensor(target['size'], dtype=torch.float)  # 用于恢复真实尺寸
        # if self.mode == 'keypoints':
        #     target['keypoints'] = torch.tensor(target['keypoints'], dtype=torch.float)

        if target['boxes'].shape[0] == 0:
            flog.debug('二次检查出错 %s', index)
            return self.__getitem__(index + 1)

        if len(target['boxes']) != len(target['labels']):
            flog.warning('!!! 数据有问题 22222  %s %s %s ', target, len(target['boxes']), len(target['labels']))
        # flog.warning('数据debug 有问题 %s %s %s ', target, len(target['boxes']), len(target['labels']))
        return img, target
Beispiel #13
0
def f_evaluate4fmap(model, data_loader, is_keep, cfg):
    '''
    1 通过 voc2fmap.py 创建 gtinfo
    2 设置 IS_FMAP_EVAL 开启 指定 PATH_EVAL_IMGS 和 PATH_EVAL_INFO 文件夹
    3 加载 classes_ids_voc
    4 支持 degbug 设置
    5 生成 dt_info label conf ltrb真实值
            tvmonitor 0.471781 0 13 174 244
            cup 0.414941 274 226 301 265
    6 f_fix_txt(gt_path, DR_PATH)  使gt 与 dt 一致
    7 f_recover_gt(gt_path)  # 恢复 gt
    8 到 D:\tb\tb\ai_code\DL\f_tools\datas\f_map\output  查看结果 查打开 f_do_fmap plot_res
    9 恢复在 CONFIG中

    :param model:
    :param data_loader:
    :param is_keep:
    :return:
    '''
    path_dt_info = data_loader.dataset.path_dt_info
    ids2classes = data_loader.dataset.ids2classes

    metric_logger = MetricLogger(delimiter="  ")
    header = "Test: "
    print_freq = max(int(len(data_loader) / 5), 1)

    for batch_data in metric_logger.log_every(data_loader, print_freq, header):
        start_time = time.time()
        _dataset = data_loader.dataset
        img_ts4, targets = batch_data
        sizes = []
        files_txt = []
        for target in targets:
            size_ = target['size']
            if is_keep:  # keep修复
                max1 = max(size_)
                size_ = [max1, max1]
            sizes.append(torch.tensor(size_))  # tesor
            # sizes.append(target['size'])
            files_txt.append(os.path.join(path_dt_info, target['name_txt']))

        ids_batch, p_boxes_ltrb, p_labels, p_scores = model(img_ts4)

        for i, (szie, file_txt) in enumerate(zip(sizes, files_txt)):
            mask = ids_batch == i  # 构建 batch 次的mask
            if torch.any(mask):  # 如果最终有目标存在 将写出info中
                lines_write = []
                for label, score, bbox in zip(p_labels[mask], p_scores[mask],
                                              p_boxes_ltrb[mask]):
                    _bbox = [
                        str(i.item())
                        for i in list((bbox *
                                       szie.repeat(2)).type(torch.int64).data)
                    ]
                    bbox_str = ' '.join(_bbox)
                    _line = ids2classes[str(int(label.item()))] + ' ' + str(
                        score.item()) + ' ' + bbox_str + '\n'
                    lines_write.append(_line)
                with open(file_txt, "w") as f:
                    f.writelines(lines_write)
            else:
                flog.warning('没有预测出框 %s', files_txt)
                pass

        end_time = time.time() - start_time
        metric_logger.update(eval_time=end_time)  # 这个填字典 添加的字段
    flog.info('dt_info 生成完成')

    # path_dt_info = data_loader.dataset.path_dt_info
    path_gt_info = data_loader.dataset.path_gt_info
    path_imgs = data_loader.dataset.path_imgs
    # f_recover_gt(path_gt_info)
    f_fix_txt(path_gt_info, path_dt_info)

    f_do_fmap(path_gt=path_gt_info,
              path_dt=path_dt_info,
              path_img=path_imgs,
              confidence=cfg.THRESHOLD_PREDICT_CONF,
              iou_map=[],
              ignore_classes=[],
              console_pinter=True,
              plot_res=False,
              animation=True)
Beispiel #14
0
def handler_face_5():
    # 这个可以直接创建json
    path_root = r'M:\AI\datas\face_5'
    path_copy_dst = os.path.join(path_root, 'images_13466')

    # file_path = os.path.join(path_root, 'train/trainImageList.txt')
    # train_type = 'train'  # train test val
    # num_file = 999999999

    file_path = os.path.join(path_root, 'train/testImageList.txt')
    train_type = 'test'  # train test val
    num_file = 200  # 这个是最大文件数

    mode = 'keypoints'  # bbox segm keypoints caption
    is_copy = False
    path_img_src = os.path.join(path_root, 'train',
                                'lfw_5590')  # is_copy = False 则无效

    # ['2007_000027.jpg', '174.0', '101.0', '349.0', '351.0', 'person']
    size_ann = 1 + 4 + 5 * 3 + 1  # 用于csv验证
    name_keypoints = [
        "left_eye",
        "right_eye",
        "nose",
        "left_mouth",
        "right_mouth",
    ]
    skeleton = [[3, 1], [3, 2], [3, 4], [3, 5]]  # 连接顺序

    if os.path.exists(file_path):
        f = open(file_path, 'r')
    else:
        raise Exception('标签文件不存在: %s' % file_path)
    lines = f.readlines()
    idx = 0
    res = []  # 标签数
    ''' 创建类型cls文件 '''
    name_cls = 'human_face'
    classes_ids = {name_cls: 1}  # 1开始
    cre_cls_json(classes_ids, name_cls, path_root)

    t_names = set()  # 用于验证重复
    for line in tqdm(lines[:num_file], desc='标注框个数'):
        msg = line.strip().split(' ')
        idx += 1
        # print('idx-', idx, ' : ', len(msg))

        file_path = msg[0]
        # print(file_path)
        file_name = file_path.split('\\')[1]
        bbox = [msg[1], msg[3], msg[2], msg[4]]  # list不支持数组索引
        keypoint = msg[5:15]
        keypoint_coco = []
        for i in range(int(len(keypoint) / 2)):
            # 转换并添加2
            x = keypoint[i * 2 + 0]
            y = keypoint[i * 2 + 1]
            if float(x) == 0 and float(y) == 0:
                flog.warning('xy均为0 %s', line)
                keypoint_coco.extend([x, y, '0'])
            else:
                keypoint_coco.extend([x, y, '2'])

        _t = []
        # 类别在后面写入时加的
        _t.append(file_name)
        _t.extend(bbox)
        _t.extend(keypoint_coco)
        t_names.add(file_name)
        # _t.extend(name_cls)  # 写死

        res.append(_t)

    copy_img(file_path, is_copy, path_copy_dst, path_img_src, t_names)
    ''' 创建csv 文件格式 [文件名,box,keypoint,类型] '''
    file_csv = cre_csv(name_cls, path_root, res, train_type)

    annotations = pd.read_csv(file_csv, header=None).values
    to_coco_4keypoint(
        annotations,
        classes_ids,
        path_copy_dst,
        path_root,
        size_ann=size_ann,
        name_keypoints=name_keypoints,
        skeleton=skeleton,
        is_copy=False,
        is_move=False,
        file_coco=mode + '_' + train_type + '_' + str(len(res))  # 标签数
    )
Beispiel #15
0
def data_clean(coco_obj, coco_img_ids, catid2clsid, path_img=None):
    '''
    用于加载coco 查看和清理无效GT 后用于训练
    :param coco_obj:
    :param coco_img_ids:
    :param catid2clsid: {1: 0, 2: 1, 3: 2}
    :param path_img:
    :return:
    '''
    records = []
    ct = 0
    for img_id in coco_img_ids:
        img_info = coco_obj.loadImgs(img_id)[0]
        file_name = img_info['file_name']
        im_w = float(img_info['width'])
        im_h = float(img_info['height'])

        ins_anno_ids = coco_obj.getAnnIds(imgIds=img_id,
                                          iscrowd=False)  # 读取这张图片所有标注anno的id
        instances = coco_obj.loadAnns(
            ins_anno_ids)  # 这张图片所有标注anno。每个标注有'segmentation'、'bbox'、...

        coco_targets = []
        anno_id = []  # 注解id
        for inst in instances:
            # print("inst['bbox']", inst['bbox'])
            # 确保 ltwh 点在图片中  coco默认 ltwh
            x, y, box_w, box_h = inst['bbox']  # 读取物体的包围框
            x1 = max(0, x)
            y1 = max(0, y)
            x2 = min(im_w - 1, x1 + max(0, box_w - 1))
            y2 = min(im_h - 1, y1 + max(0, box_h - 1))  # ltwh -> ltrb
            if inst['area'] > 0 and x2 >= x1 and y2 >= y1:
                inst['clean_bbox'] = [x1, y1, x2, y2]  # inst增加一个键值对
                # print("inst['clean_bbox']", inst['clean_bbox'])
                coco_targets.append(inst)  # 这张图片的这个物体标注保留
                anno_id.append(inst['id'])
            else:
                flog.warning(
                    'Found an invalid bbox in annotations: im_id: {}, '
                    'area: {} x1: {}, y1: {}, x2: {}, y2: {}.'.format(
                        img_id, float(inst['area']), x1, y1, x2, y2))

        num_bbox = len(coco_targets)  # 这张图片的物体数

        # 左上角坐标+右下角坐标+类别id
        gt_bbox = np.zeros((num_bbox, 4), dtype=np.float32)
        gt_class = np.zeros((num_bbox, 1), dtype=np.int32)
        gt_score = np.ones((num_bbox, 1), dtype=np.float32)  # 得分的标注都是1
        is_crowd = np.zeros((num_bbox, 1), dtype=np.int32)
        difficult = np.zeros((num_bbox, 1), dtype=np.int32)
        gt_poly = [None] * num_bbox

        for i, target in enumerate(coco_targets):
            catid = target['category_id']
            gt_class[i][0] = catid2clsid[catid]  # id类型顺序转换
            gt_bbox[i, :] = target['clean_bbox']
            is_crowd[i][0] = target['iscrowd']
            if 'segmentation' in target:
                gt_poly[i] = target['segmentation']  # 分割

        if path_img is not None:
            file_img = os.path.join(path_img, file_name)
            img_pil = Image.open(file_img).convert('RGB')  # 原图数据
            f_show_3box4pil(img_pil, gt_bbox, is_oned=False)

        coco_rec = {
            'im_file': file_name,
            'im_id': np.array([img_id]),
            'h': im_h,
            'w': im_w,
            'is_crowd': is_crowd,
            'gt_class': gt_class,
            'anno_id': anno_id,
            'gt_bbox': gt_bbox,
            'gt_score': gt_score,
            'gt_poly': gt_poly,
        }

        # 显示文件信息
        # flog.debug('Load file: {}, im_id: {}, h: {}, w: {}.'.format(file_names, img_id, im_h, im_w))
        records.append(coco_rec)  # 注解文件。
        ct += 1
    flog.info('加载 {} 个图片 .'.format(ct))
    return records
Beispiel #16
0
    def load_anns(self, index, img_wh):
        '''
        ltwh --> ltrb
        :param index:
        :return:
            bboxs: np(num_anns, 4)
            labels: np(num_anns)
        '''
        # annotation_ids = self.coco.getAnnIds(self.image_ids[index], iscrowd=False)
        annotation_ids = self.coco_obj.getAnnIds(self.ids_img[index])  # ann的id
        # anns is num_anns x 4, (x1, x2, y1, y2)
        bboxs_np = np.zeros((0, 4), dtype=np.float32)  # np创建 空数组 高级
        labels = []
        keypoints_np = []
        # skip the image without annoations
        if len(annotation_ids) == 0:
            return None

        coco_anns = self.coco_obj.loadAnns(annotation_ids)
        for a in coco_anns:
            x, y, box_w, box_h = a['bbox']  # ltwh
            # 得 ltrb
            x1 = max(0, x)  # 修正lt最小为0 左上必须在图中
            y1 = max(0, y)
            x2 = min(img_wh[0] - 1, x1 + max(0, box_w - 1))  # 右下必须在图中
            y2 = min(img_wh[1] - 1, y1 + max(0, box_h - 1))
            if a['area'] > 0 and x2 >= x1 and y2 >= y1:
                a['bbox'] = [x1, y1, x2, y2]  # 修正 并写入ltrb
            else:
                flog.warning('标记框有问题 %s 跳过', a)
                continue

            bbox = np.zeros((1, 4), dtype=np.float32)
            bbox[0, :4] = a['bbox']

            if self.mode == 'keypoints':
                '''
                # 如果关键点在物体segment内,则认为可见.
           		# v=0 表示这个关键点没有标注(这种情况下x=y=v=0)
           		# v=1 表示这个关键点标注了但是不可见(被遮挡了)
           		# v=2 表示这个关键点标注了同时也可见
                '''
                keypoints = self.handle_keypoints(a)
                if keypoints is None:
                    flog.warning('全0 keypoints %s 跳过')
                    continue
                keypoints_np.append(keypoints)

            # 全部通过后添加
            bboxs_np = np.append(bboxs_np, bbox, axis=0)
            labels.append(self.ids_old_new[a['category_id']])

        # bboxs = ltwh2ltrb(bboxs) # 前面 已转
        if bboxs_np.shape[0] == 0:
            flog.error('这图标注 不存在 %s', coco_anns)
            return None
            # raise Exception('这图标注 不存在 %s', coco_anns)

        # 转tensor
        if self.mode == 'bbox':
            return [torch.tensor(bboxs_np, dtype=torch.float), torch.tensor(labels, dtype=torch.float)]
        elif self.mode == 'keypoints':
            keypoints_np = np.array(keypoints_np)  # list转np
            # 有标注的情况下 keypoints_np 一定有
            return [torch.tensor(bboxs_np, dtype=torch.float),
                    torch.tensor(labels, dtype=torch.float),
                    torch.tensor(keypoints_np, dtype=torch.float)]
Beispiel #17
0
def load_weight(file_weight,
                model,
                optimizer=None,
                lr_scheduler=None,
                device=torch.device('cpu'),
                is_mgpu=False,
                ffun=None):
    start_epoch = 0

    # 只匹配需要的
    # model_dict = model.state_dict() # 获取模型每层的参数阵
    # checkpoint = torch.load(file_weight, map_location=device)
    # pretrained_dict = checkpoint['model']
    # dd = {}
    # for k, v in pretrained_dict.items():
    #     if k in model_dict:
    #         shape_1 = model_dict[k].shape
    #         shape_2 = pretrained_dict[k].shape
    #         if shape_1 == shape_2:
    #             dd[k] = v
    #         else:
    #             print('shape mismatch in %s. shape_1=%s, while shape_2=%s.' % (k, shape_1, shape_2))
    # model_dict.update(dd)
    # model.load_state_dict(model_dict)
    # flog.warning('手动加载完成:%s',file_weight)
    # return start_epoch

    if file_weight and os.path.exists(file_weight):
        checkpoint = torch.load(file_weight, map_location=device)
        '''对多gpu的k进行修复'''
        if 'model' in checkpoint:
            pretrained_dict_y = checkpoint['model']
        else:
            pretrained_dict_y = checkpoint

        # 特殊处理
        # if True:
        #     del pretrained_dict['module.head_yolov1.weight']
        #     del pretrained_dict['module.head_yolov1.bias']
        #     # del pretrained_dict['module.ClassHead.1.conv1x1.weight']
        #     # del pretrained_dict['module.ClassHead.1.conv1x1.bias']
        #     # del pretrained_dict['module.ClassHead.2.conv1x1.weight']
        #     # del pretrained_dict['module.ClassHead.2.conv1x1.bias']
        #     model.load_state_dict(pretrained_dict, strict=False)
        #     start_epoch = checkpoint['epoch'] + 1
        #     flog.error('已特殊加载 feadre 权重文件为 %s', file_weight)
        #     return start_epoch
        ''' debug '''
        if ffun is not None:
            pretrained_dict = ffun(pretrained_dict_y)
        else:
            pretrained_dict = pretrained_dict_y

        dd = {}

        # 多GPU处理
        ss = 'module.'
        for k, v in pretrained_dict.items():
            if is_mgpu:
                if ss not in k:
                    dd[ss + k] = v
                else:
                    dd = pretrained_dict_y
                    break
                    # dd[k] = v
            else:
                dd[k.replace(ss, '')] = v
        '''重组权重'''
        # load_weights_dict = {k: v for k, v in weights_dict.items()
        #                      if model.state_dict()[k].numel() == v.numel()}

        keys_missing, keys_unexpected = model.load_state_dict(dd, strict=False)
        if len(keys_missing) > 0 or len(keys_unexpected):
            flog.error('missing_keys %s', keys_missing)  # 这个是 model 的属性
            flog.error('unexpected_keys %s', keys_unexpected)  # 这个是 pth 的属性
        if optimizer:
            optimizer.load_state_dict(checkpoint['optimizer'])
        if lr_scheduler and checkpoint['lr_scheduler']:
            lr_scheduler.load_state_dict(checkpoint['lr_scheduler'])

        if 'epoch' in checkpoint:
            start_epoch = checkpoint['epoch'] + 1
        else:
            start_epoch = 0

        flog.warning('已加载 feadre 权重文件为 %s', file_weight)
    else:
        # raise Exception(' 未加载 feadre权重文件 ')
        flog.error(' 未加载 feadre权重文件 %s', file_weight)
        if fis_mgpu():
            path = os.path.join(tempfile.gettempdir(), "_init_weights_tmp.pt")
            checkpoint_path = path
            if is_main_process():
                torch.save(model.state_dict(), checkpoint_path)

            # import torch.distributed as dist
            torch.distributed.barrier()  # 多GPU阻塞
            model.load_state_dict(
                torch.load(checkpoint_path, map_location=device))
            flog.error('已默认加载临时文件 %s', path)
    return start_epoch
Beispiel #18
0
    coco_obj = COCO(file_json)
    id_ = 1
    image_info = coco_obj.loadImgs(id_)[0]
    file_img = os.path.join(path_img, image_info['file_name'])
    img_np = cv2.imread(file_img)

    annotation_ids = coco_obj.getAnnIds(id_)
    bboxs = np.zeros((0, 4), dtype=np.float32)  # np创建 空数组 高级
    labels = []

    coco_anns = coco_obj.loadAnns(annotation_ids)
    for a in coco_anns:
        # skip the annotations with width or height < 1
        if a['bbox'][2] < 1 or a['bbox'][3] < 1:
            flog.warning('标记框有问题 %s', a)
            continue

        labels.append(a['category_id'])
        bbox = np.zeros((1, 4), dtype=np.float32)
        bbox[0, :4] = a['bbox']
        bboxs = np.append(bboxs, bbox, axis=0)

    bboxs_ltrb = ltwh2ltrb(bboxs)

    # f_plt_show_cv(img_np, gboxes_ltrb=torch.tensor(bboxs_ltrb), labels_text=labels, is_recover_size=False)

    # fd = RandomMirror()
    # fd = Expand(mean=(0.406, 0.456, 0.485))
    # fd = RandomSampleCrop()
    # fd = Normalize(mean=(0.406, 0.456, 0.485), std=(0.225, 0.224, 0.229))