示例#1
0
def parse_args():
    """
    处理脚本参数,支持相对路径
    img_file 文件路径,默认文件夹:img_downloader/urls
    out_folder 输出文件夹,默认文件夹:img_data
    :return: arg_img,文件路径;out_folder,输出文件夹
    """
    parser = argparse.ArgumentParser(description='下载数据脚本')
    parser.add_argument('--img_file', required=True, help='文件路径', type=str)
    parser.add_argument('--out_folder', help='输出文件夹', type=str)
    args = parser.parse_args()

    arg_img = args.img_file
    if len(arg_img.split('/')) == 1:
        arg_img = os.path.join(ROOT_DIR, 'img_downloader', 'urls', arg_img)
    print_info("文件路径:%s" % arg_img)

    arg_out = args.out_folder
    if not arg_out:
        file_name = arg_img.split('/')[-1]
        arg_out = os.path.join(ROOT_DIR, 'img_data', file_name)
    elif len(arg_out.split('/')) == 1:
        arg_out = os.path.join(ROOT_DIR, 'img_data', arg_out)
    print_info("输出文件夹:%s" % arg_out)
    return arg_img, arg_out
示例#2
0
def format_img_and_anno(img_folder):
    """
    格式化输出。图片和标注文件夹
    :param img_folder: 图片文件夹
    :return:
    """
    file_paths, file_names = traverse_dir_files(img_folder)
    img_dict = dict()  # 将标注和图片路径,生成一个字典

    for file_path, file_name in zip(file_paths, file_names):
        if file_name.endswith('.jpg'):
            name = file_name.replace('.jpg', '')
            if name not in img_dict:
                img_dict[name] = (None, None)
            (img_p, anno_p) = img_dict[name]
            img_dict[name] = (file_path, anno_p)

        if file_name.endswith('.xml'):
            name = file_name.replace('.xml', '')
            if name not in img_dict:
                img_dict[name] = (None, None)
            (img_p, anno_p) = img_dict[name]
            img_dict[name] = (img_p, file_path)

    print_info('图片数: {}'.format(len(img_dict.keys())))
    return img_dict
示例#3
0
    def detect_img(self, yolo, img_path, anno_path, out_folder=None):
        """
        检测图片,与标注对比
        :param yolo: YOLO
        :param img_path: 图片路径
        :param anno_path: 标注路径
        :param out_folder: 存储错误图像
        :return:
        """
        img_data = Image.open(img_path)
        boxes, scores, classes = yolo.__detect_img_facets(img_data)
        boxes = self.reform_boxes(boxes)
        print_info('检测: {}'.format(boxes))

        anno_boxes, name_list = read_anno_xml(anno_path)
        anno_boxes = self.reform_boxes2(anno_boxes)
        print_info('真值: {}'.format(anno_boxes))

        precision, recall = self.iou_of_boxes(boxes, anno_boxes)

        if True or out_folder and (precision != 1.0 or recall != 1.0):
            img_data = yolo.draw_boxes(img_data, boxes, scores, classes,
                                       [(255, 0, 0)])
            img_data = yolo.draw_boxes(img_data, anno_boxes,
                                       [1.0 for i in range(len(anno_boxes))],
                                       [0 for i in range(len(anno_boxes))],
                                       [(128, 128, 255)])
            # 图片的缩略图
            # size = 1024, 1024
            # img_data.thumbnail(size, Image.ANTIALIAS)
            img_name = img_path.split('/')[-1]
            out_img = os.path.join(out_folder, img_name + '.d.png')
            img_data.save(out_img)  # 存储
            # img_data.show()  # 显示
        return img_path, precision, recall
示例#4
0
def detect_img_folder(img_folder, out_folder, yolo):
    mkdir_if_not_exist(out_folder)
    path_list, name_list = traverse_dir_files(img_folder)
    print_info('图片数: %s' % len(path_list))

    _, imgs_names = traverse_dir_files(out_folder)

    count = 0
    for path, name in zip(path_list, name_list):
        if path.endswith('.gif'):
            continue

        out_name = name + '.d.jpg'
        if out_name in imgs_names:
            print_info('已检测: %s' % name)
            continue

        print_info('检测图片: %s' % name)

        try:
            image = Image.open(path)
            out_file = os.path.join(ROOT_DIR, 'face', 'yolov3', 'output_data',
                                    'logAll_res.txt')
            r_image = yolo.detect_image(image, ('logAll/' + name), out_file)
            r_image.save(os.path.join(out_folder, name + '.d.jpg'))
        except Exception as e:
            print(e)
            pass

        count += 1
        if count % 100 == 0:
            print_info('已检测: %s' % count)
    yolo.close_session()
示例#5
0
    def __init__(self,
                 model_path='model_data/ep074-loss26.535-val_loss27.370.h5',
                 classes_path='configs/wider_classes.txt',
                 anchors_path='configs/yolo_anchors.txt'):

        self.model_path = model_path  # 模型文件
        self.classes_path = classes_path  # 类别文件
        self.anchors_path = anchors_path  # anchors文件
        print_info('模型: {}'.format(model_path))

        self.score = 0.25
        self.iou = 0.30
        print_info('置信度: {}, IoU: {}'.format(self.score, self.iou))  # 输出参数

        self.class_names = self._get_class()  # 获取类别
        self.anchors = self._get_anchors()  # 获取anchor
        self.sess = K.get_session()
        print_info('anchors: {}, 类别: {}'.format(len(self.anchors),
                                                len(self.class_names)))

        self.model_image_size = (416, 416)  # fixed size or (None, None), hw
        print_info('图片尺寸: {}'.format(self.model_image_size))  # 输出参数

        self.yolo_model = None
        self.colors = None
        self.input_image_shape = None

        self.boxes, self.scores, self.classes = self.generate()
示例#6
0
    def iou_of_boxes(boxes1, boxes2):
        """
        框的IOU
        :param boxes1_: 真值
        :param boxes2_: 预测
        :return: 精准和召回
        """
        res_list = []

        boxes1_ = copy.deepcopy(boxes1)
        boxes2_ = copy.deepcopy(boxes2)

        t1, t2 = len(boxes1_), len(boxes2_)

        for box1 in boxes1_:
            final_iou = 0
            final_box = None
            for box2 in boxes2_:
                iou = bb_intersection_over_union(box1, box2)
                if iou > final_iou:
                    final_iou = iou
                    final_box = box2
            if final_iou > 0.5:
                res_list.append((box1, final_box, final_iou))
                boxes2_.remove(final_box)

        tr = len(res_list)

        if tr == 0:  # 没有检测源, 则认为正确
            if t1 == 0 and t2 != 0:
                recall, precision = 1.0, 0.0
            elif t1 != 0 and t2 == 0:
                recall, precision = 0.0, 1.0
            elif t1 != 0 and t2 != 0:
                recall, precision = 0.0, 0.0
            else:
                recall, precision = 1.0, 1.0
        else:
            recall = safe_div(tr, t1)  # 召回率
            precision = safe_div(tr, t2)  # 精准率

        print_info('精准: {:.4f}, 召回: {:.4f}, 匹配结果: {}'.format(
            precision, recall, res_list))

        return [precision, recall]
示例#7
0
    def load_model(self):
        net = DarkNet(input_dim=self.input_dim,
                      num_classes=self.num_classes)  # 基础网络DarkNet
        net.initialize(ctx=self.ctx)

        if self.params_path.endswith(".params"):  # 加载模型
            net.load_params(self.params_path)
        elif self.params_path.endswith(".weights"):
            tmp_batch = nd.uniform(shape=(1, 3, self.input_dim,
                                          self.input_dim),
                                   ctx=self.ctx)
            net(tmp_batch)
            net.load_weights(self.params_path, fine_tune=False)
        else:
            print("params {} load error!".format(self.params_path))
            exit()
        print_info("加载参数: {}".format(self.params_path))
        net.hybridize()

        return net
示例#8
0
def download_imgs_for_mp(img_file, out_folder, prefix=None, n_prc=10):
    """
    多线程下载
    :param img_file: 图片文件
    :param out_folder: 输出文件夹
    :param prefix: 图片前缀
    :param n_prc: 进程数, 默认40个
    :return: None
    """
    print_info('进程总数: %s' % n_prc)
    pool = Pool(processes=n_prc)  # 多线程下载
    paths_list = read_file(img_file)
    print_info('文件数: %s' % len(paths_list))

    _, imgs_names = traverse_dir_files(out_folder)

    for (index, path) in enumerate(paths_list):
        if prefix:
            pool.apply_async(download_img,
                             (path, out_folder, imgs_names,
                              prefix + '_' + str(index) + '.jpg'))
        else:
            pool.apply_async(download_img, (path, out_folder, imgs_names))

    pool.close()
    pool.join()

    # _, imgs_names = traverse_dir_files(out_folder)
    # print_info('图片总数: %s' % len(imgs_names))
    print_info('全部下载完成')
示例#9
0
    def verify_model(self):
        """
        处理标记文件夹
        :param img_folder: 图片文件夹
        :param out_folder:
        :return:
        """
        yolo = YoloV3(model_path=self.model_path,
                      classes_path=self.classes_path,
                      anchors_path=self.anchors_path)  # yolo算法类

        img_dict = format_img_and_anno(self.img_folder)

        res_dict = dict()
        for count, img_name in enumerate(img_dict):
            print_info('-' * 50)
            print_info('图片: {}'.format(img_name))
            (img_p, anno_p) = img_dict[img_name]
            _, precision, recall = self.detect_img(yolo, img_p, anno_p,
                                                   self.out_folder)
            res_dict[img_name] = (precision, recall)
            if count == 10:
                break

        ap, ar = 0, 0
        for name in res_dict.keys():
            precision, recall = res_dict[name]
            ap += precision
            ar += recall

        mAp = safe_div(ap, len(res_dict.keys()))
        mAr = safe_div(ar, len(res_dict.keys()))
        print_info('平均精准率: {:.4f} %, 平均召回率: {:.4f} %'.format(
            mAp * 100, mAr * 100))
示例#10
0
    def __load_model(self):
        """
        加载网络模型
        :return: 网络
        """
        net = DarkNet(input_dim=self.input_dim, num_classes=self.num_classes)  # 基础网络 DarkNet
        net.initialize(ctx=self.ctx)  # 网络环境 cpu or gpu

        print_info("模型: {}".format(self.params_path))

        if self.params_path.endswith(".params"):  # 加载参数
            net.load_params(self.params_path)
        elif self.params_path.endswith(".weights"):  # 加载模型
            tmp_batch = nd.uniform(shape=(1, 3, self.input_dim, self.input_dim), ctx=self.ctx)
            net(tmp_batch)
            net.load_weights(self.params_path, fine_tune=False)
        else:
            raise Exception('模型错误')  # 抛出异常

        net.hybridize()  # 编译和优化网络

        return net
示例#11
0
def download_img(img_url, out_folder, imgs_names, img_name=None):
    """
    下载图片
    :param img_url: 图片URL
    :param out_folder: 输出文件夹
    :param imgs_names: 已有图片
    :param img_name: 图片名称
    :return: None
    """
    if not img_name:
        img_name = img_url.split('/')[-1]  # 图片文件名

    if img_name in imgs_names:
        print_info('图片已存在: %s' % img_name)
        return

    img_data = requests.get(img_url).content

    out_file = os.path.join(out_folder, img_name)  # 输出文件

    with open(out_file, 'wb') as hl:
        hl.write(img_data)
        print_info('图片已下载: %s' % img_name)
示例#12
0
def download_imgs(img_file, out_folder, prefix=None):
    """
    下载图片集合
    :param img_file: 图片文件
    :param out_folder: 文件夹
    :param prefix: 文件前缀
    :return: None
    """
    paths_list = read_file(img_file)
    print_info('图片总数: %s' % len(paths_list))

    _, imgs_names = traverse_dir_files(out_folder)

    count = 0
    for (index, path) in enumerate(paths_list):
        if prefix:
            download_img(path, out_folder, imgs_names,
                         prefix + '_' + str(index) + '.jpg')
        else:
            download_img(path, out_folder, imgs_names)
        count += 1
        if count % 200 == 0:
            print_info('已下载: %s' % count)
示例#13
0
    def iou_of_boxes(boxes1, boxes2):
        res_list = []
        for box1 in boxes1:
            final_iou = 0
            final_box = None
            for box2 in boxes2:
                iou = bb_intersection_over_union(box1, box2)
                if iou > final_iou:
                    final_iou = iou
                    final_box = box2
            if final_iou > 0.5:
                res_list.append((box1, final_box, final_iou))

        t1, t2, tr = len(boxes1), len(boxes2), len(res_list)

        if tr == 0:  # 没有检测源, 则认为正确
            return [1.0, 1.0]

        recall = safe_div(tr, t1)  # 召回率
        precision = safe_div(tr, t2)  # 精准率
        print_info('精准: {:.4f}, 召回: {:.4f}, 匹配结果: {}'.format(
            precision, recall, res_list))
        return [precision, recall]
示例#14
0
    def detect_image_facets(self, image):
        """
        检测图片的数据细节,检测框、置信度、类别
        :param image: PIL图片
        :return: 检测框、置信度、类别
        """
        start_t = timer()  # 起始时间
        print_info('{}检测开始{}'.format('-' * 10, '-' * 10))

        if self.model_image_size != (
                None, None):  # 416x416, 416=32*13,必须为32的倍数,最小尺度是除以32
            assert self.model_image_size[
                0] % 32 == 0, 'Multiples of 32 required'
            assert self.model_image_size[
                1] % 32 == 0, 'Multiples of 32 required'
            boxed_image = letterbox_image(image,
                                          tuple(reversed(
                                              self.model_image_size)))  # 填充图像
        else:
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            boxed_image = letterbox_image(image, new_image_size)  # 强制转换为32的倍数

        image_data = np.array(boxed_image, dtype='float32')  # 图片数据
        image_data /= 255.  # 转换0~1
        image_data = np.expand_dims(image_data, 0)  # 添加批次维度,将图片增加1维

        # 参数盒子、得分、类别;输入图像0~1,4维;原始图像的尺寸
        out_boxes, out_scores, out_classes = self.sess.run(
            [self.boxes, self.scores, self.classes],
            feed_dict={
                self.yolo_model.input: image_data,  # 输入检测图片
                self.input_image_shape: [image.size[1],
                                         image.size[0]],  # 输入检测尺寸
                K.learning_phase(): 0  # 学习率, 0表示测试, 1表示训练
            })

        print_info('检测时间: {:.4f} 秒'.format(timer() - start_t))  # 检测执行时间
        print_info('检测物体数: {} 个'.format(len(out_boxes)))  # 检测结果
        print_info('{}检测结束{}'.format('-' * 10, '-' * 10))

        return out_boxes, out_scores, out_classes
示例#15
0
    def verify_model(self):
        """
        处理标记文件夹
        :param img_folder: 图片文件夹
        :param out_folder:
        :return:
        """
        img_dict = format_img_and_anno(self.img_folder)

        res_list = []
        for count, img_name in enumerate(img_dict):
            print_info('-' * 50)
            print_info('图片: {}'.format(img_name))
            (img_p, anno_p) = img_dict[img_name]
            try:
                res_dict = self.detect_img(img_p, anno_p, self.out_folder)
            except Exception as e:
                print_ex('检测异常: {}'.format(e))
                continue
            res_list.append(res_dict)
            # if count == 10:
            #     break
        print_info('-' * 50)

        for target_name in (['all'] + self.targets_name):
            if target_name in ['truck', 'bus']:
                continue
            ap, ar, count = 0, 0, 0
            for pr_dict in res_list:
                if target_name in pr_dict:
                    tp, tr = pr_dict[target_name]
                    ap += tp
                    ar += tr
                    count += 1
            mAp = safe_div(ap, count)
            mAr = safe_div(ar, count)

            print_info('类: {} P: {:.4f} %, R: {:.4f} %'.format(
                target_name, mAp * 100, mAr * 100))
示例#16
0
def process_anno_folder(img_folder, out_folder):
    img_dict = format_img_and_anno(img_folder)
    _, file_names = traverse_dir_files(out_folder)

    for count, img_name in enumerate(img_dict.keys()):
        print_info('-' * 50)

        (img_p, anno_p) = img_dict[img_name]
        if not img_p or not anno_p:
            print_info('图片: {} 异常'.format(img_name))
            continue
        if img_name in file_names:
            print_info('图片: {} 已存在'.format(img_name))
        else:
            print_info('图片: {}'.format(img_name))

        image_data = Image.open(img_p)
        boxes_list, name_list = read_anno_xml(anno_p)
        prob_list = [1.0 for x in range(len(boxes_list))]
        img_boxes = draw_boxes_simple(image_data, boxes_list, prob_list,
                                      name_list)

        img_boxes.save(os.path.join(out_folder, img_name + '.d.jpg'))
示例#17
0
def main():
    ym = Y3Model()
    img_folder = os.path.join(IMG_DATA, 'jiaotong-0727')
    right_folder = os.path.join(IMG_DATA, 'jiaotong-0727-right')
    wrong_folder = os.path.join(IMG_DATA, 'jiaotong-0727-wrong')
    none_folder = os.path.join(IMG_DATA, 'jiaotong-0727-none')
    mkdir_if_not_exist(right_folder, is_delete=True)
    mkdir_if_not_exist(wrong_folder, is_delete=True)
    mkdir_if_not_exist(none_folder, is_delete=True)
    img_dict = format_img_and_anno(img_folder)

    r_count = 0
    all_count = 0
    no_recall_count = 0

    for count, img_name in enumerate(img_dict):
        (img_p, anno_p) = img_dict[img_name]
        # print(img_p)
        try:
            tag_res, img_box = ym.detect_img(img_p, True)
        except Exception as e:
            continue

        w_tags = []
        for tag in tag_res.keys():
            if tag_res[tag] <= 0.01:
                print_info('删除Tag {} {}'.format(tag, tag_res[tag]))
                w_tags.append(tag)
        for tag in w_tags:
            tag_res.pop(tag, None)  # 小于1%的类别

        all_count += 1
        p_classes = set(tag_res.keys())

        _, t_classes = read_anno_xml(anno_p)
        merge_dict = {'truck': 'car', 'bus': 'car', 'car': 'car'}  # 合并类别
        t_classes = map_classes(merge_dict, t_classes)  # 合并类别
        traffic_names = [
            'bicycle', 'car', 'motorbike', 'aeroplane', 'bus', 'train',
            'truck', 'boat'
        ]
        t_classes = set(t_classes) & set(traffic_names)

        img_name = img_p.split('/')[-1]
        is_right = False

        if p_classes and p_classes.issubset(t_classes):  # 检测正确
            r_count += 1
            img_box.save(os.path.join(right_folder, img_name + '.d.jpg'))
            is_right = True
        elif not p_classes and not t_classes:  # 空,检测正确
            r_count += 1
            if not img_box:
                img_box = Image.open(img_p)
            img_box.save(os.path.join(right_folder, img_name + '.d.jpg'))
            is_right = True
        elif not p_classes and t_classes:  # 检测为空,实际有类
            if not img_box:
                img_box = Image.open(img_p)
            img_box.save(os.path.join(none_folder, img_name + '.d.jpg'))
            no_recall_count += 1  # 未召回
            r_count += 1
            is_right = True
        else:  # 其他,检测错误
            if not img_box:
                img_box = Image.open(img_p)
            img_box.save(os.path.join(wrong_folder, img_name + '.d.jpg'))

        print_info('P: {}, T: {}, {}'.format(list(p_classes), list(t_classes),
                                             '正确' if is_right else '错误'))

    right_ratio = safe_div(r_count, all_count)
    print_info('正确: {}, 全部: {}, 未召回: {}, 准确率: {}'.format(
        r_count, all_count, no_recall_count, right_ratio))
示例#18
0
    def detect_img(self, img_path, xml_path, out_folder=None):
        color_list_1 = make_line_colors(n_color=20, alpha=0.6, bias=1.0)
        color_list_2 = make_line_colors(n_color=20, alpha=1.0, bias=0.8)

        car_list = ['truck', 'bus', 'car']

        # img_path = os.path.join(IMG_DATA, 'jiaotong-0727', '6emekgFq0neQv8ELXmCq5aQnL3Zz.jpg')
        # xml_path = os.path.join(IMG_DATA, 'jiaotong-0727', '6emekgFq0neQv8ELXmCq5aQnL3Zz.xml')
        img_data = Image.open(img_path)

        boxes, scores, classes_no = self.detect_image_facets(img_path)  # 检测图片
        boxes = self.reform_boxes(boxes)
        classes = [self.classes_name[int(i)]
                   for i in classes_no]  # 将classes的no转换为name
        boxes, scores, classes = filter_sbox(
            (img_data.size[0], img_data.size[1]), (boxes, scores, classes))
        boxes, scores, classes = self.keep_classes(self.targets_name, boxes,
                                                   scores, classes)
        classes = self.merge_classes_name(car_list, 'car', classes)
        print_info('检测数: {} - {}'.format(len(boxes), classes))

        t_boxes, t_classes = read_anno_xml(xml_path)
        t_scores = ['T' for i in range(len(t_boxes))]
        t_boxes, t_scores, t_classes = \
            filter_sbox((img_data.size[0], img_data.size[1]), (t_boxes, t_scores, t_classes))
        t_boxes, t_scores, t_classes = self.keep_classes(
            self.targets_name, t_boxes, t_scores, t_classes)
        t_classes = self.merge_classes_name(car_list, 'car', t_classes)
        print_info('真值数: {}'.format(len(t_boxes), t_classes))

        uni_classes = sorted(list(set(classes) | set(t_classes)))
        color_dict_1 = dict(zip(uni_classes, color_list_1[:len(uni_classes)]))
        color_dict_2 = dict(zip(uni_classes, color_list_2[:len(uni_classes)]))

        img_true = draw_boxes_simple(img_data, t_boxes, t_scores, t_classes,
                                     color_dict_2)
        # img_true.show()
        img_pred = draw_boxes_simple(img_data,
                                     boxes,
                                     scores,
                                     classes,
                                     color_dict_1,
                                     is_alpha=True)
        # img_pred.show()
        if out_folder:
            img_name = img_path.split('/')[-1]
            out_img = os.path.join(out_folder, img_name + '.d.png')
            img_pred.save(out_img)  # 存储

        res_dict = dict()

        # print('all')
        print_info('交通工具')
        ap, ar = self.iou_of_boxes(t_boxes, boxes)
        res_dict['all'] = (ap, ar)
        print_info('')

        for class_name in uni_classes:
            print_info('类别: {}'.format(class_name))
            sub_t_boxes, sub_t_classes = self.filter_class(
                class_name, t_boxes, t_classes)
            sub_boxes, sub_classes = self.filter_class(class_name, boxes,
                                                       classes)
            ap, ar = self.iou_of_boxes(sub_t_boxes, sub_boxes)
            res_dict[class_name] = (ap, ar)

        return res_dict