目标检测问题的ROC曲线(半成品)

版权声明:希望我的博客可以为别人带去知识与便利,让那些像我曾经一样迷茫的小伙伴不再迷茫~ https://blog.csdn.net/qq_34374664/article/details/81395159

get_para.py

# coding-utf-8
import IoU


# 本模块获取参数,网上规则众多,这里采用https://blog.csdn.net/qq_34374664/article/details/81368316的方法,他是翻译FDDB的官方文档
# 此函数获得对应阈值的TP,FP,TT
def get_para(threshold, iou_threshold = 0.3):
    #gt = open('/home/kk17/PythonProject/dataset/FDDB/ellipseList.txt', 'r')
    #dt = open('/home/kk17/PythonProject/dataset/FDDB/results.txt', 'r')
    gt = open('ellipseList.txt', 'r')
    dt = open('results.txt', 'r')
    # print(dt)
    dt_page = dt.readlines()
    dt_page_len = len(dt_page)
    gt_page = gt.readlines()
    # gt_page_len = len(gt_page)
    dt_i = 0
    gt_i = 0
    tp = 0
    fp = 0
    tt = 0  # 代表真实值就是1的样本数量
    while dt_i < dt_page_len:
        # print(gt_page[gt_i])
        # input()
        gt_string_len = len(gt_page[gt_i])
        # print(gt_string_len)
        if gt_string_len < 11:  # ///
            continue

        if (gt_page[gt_i][0] == '2') & (gt_page[gt_i][1] == '0') & (gt_page[gt_i][2] == '0') & (
                (gt_page[gt_i][3] == '2') | (gt_page[gt_i][3] == '3')):
            gt_i = gt_i + 1
            gt_face_num = int(gt_page[gt_i].split('\n')[0])
            tt = tt + gt_face_num
            # gt_i = gt_i + gt_face_num + 1  # 移动gt列表的下标
       # print(gt_face_num)
        if gt_face_num == 0:
            gt_i = gt_i + 1
            continue
        dt_string_len = len(dt_page[dt_i])
        if dt_string_len < 11:  # 要加上长度判断 如果遇到是脸的个数,那样会小于4,所以下面代码会产生越界,python判断语句好像不能false直接退出
            continue  # ///
        if (dt_page[dt_i][0] == '2') & (dt_page[dt_i][1] == '0') & (dt_page[dt_i][2] == '0') & ((dt_page[dt_i][3] == '2') | (dt_page[dt_i][3] == '3')):
            dt_i = dt_i + 1
            dt_face_num = int(dt_page[dt_i].split('\n')[0])
            # dt_i = dt_i + dt_face_num + 1  # 移动dt列表的下标
            # print(face_num)
        if dt_face_num == 0:  # ///
            dt_i = dt_i + 1
            gt_i = gt_i + gt_face_num + 1
            continue
        for di in range(1, dt_face_num+1):
            dt_rectangle = dt_page[dt_i+di].split('\n')[0]
            dt_rectangle = dt_rectangle.split(' ')
            # print(dt_rectangle)
            for gi in range(1, gt_face_num + 1):
                gt_ellipse = gt_page[gt_i+gi].split('\n')[0]
                gt_ellipse = gt_ellipse.split(' ')
                iou = IoU.iou(float(dt_rectangle[0]), float(dt_rectangle[1]), float(dt_rectangle[2]), float(dt_rectangle[3]), float(gt_ellipse[0]),
                              float(gt_ellipse[1]), float(gt_ellipse[2]), float(gt_ellipse[3]), float(gt_ellipse[4]))
                if iou >= iou_threshold:
                    if float(dt_rectangle[4]) >= threshold:
                        tp = tp + 1
                if iou < iou_threshold:
                    if float(dt_rectangle[4]) >= threshold:
                        fp = fp + 1
        gt_i = gt_i + gt_face_num + 1
        dt_i = dt_i + dt_face_num + 1

    return tp, fp, tt

draw_cure.py

# coding-utf-8
import numpy as np
import get_para
import matplotlib.pyplot as plt


def draw_roc():
    tpr = []
    fp = []
    for threshold in np.arange(0, 1, 0.02):
        para = get_para.get_para(threshold)
        tpr.append(para[0] / para[2])
        fp.append(para[1])
        print(para)
    plt.plot(fp, tpr)
    plt.show()


draw_roc()

IoU.py

# coding-utf-8


# 将椭圆转换成与坐标轴平行的矩形,具体规则是椭圆的中心也是矩形的中心,矩形的长对应着椭圆长的两倍,同理宽
# ps:本应考虑角度从而更准确的画出矩形框,但是因为角度都是-2,2,不是很理解,暂时没有加入这个步骤
def ellipse_to_rectangle(major_axis_radius, minor_axis_radius, angle, center_x, center_y):
    rectangle = [center_x + minor_axis_radius, center_y + major_axis_radius, minor_axis_radius * 2, major_axis_radius * 2]  # 左上角x,y,长宽
    return rectangle


# 计算IoU与转换函数封装在一起, 这里可以用数组,为了体现逻辑关系以及变量意义直接变量,并且就两个图形,变量不会太多

def iou(detection_x, detection_y, detection_w, detection_h, major_axis_radius, minor_axis_radius,
        angle, center_x, center_y):
    gt_x, gt_y, gt_w, gt_h = ellipse_to_rectangle(major_axis_radius, minor_axis_radius, angle, center_x, center_y)
    two_rectangle_x = [gt_x, gt_x+gt_w, detection_x, detection_x+detection_w]  # 对角线上的坐标
    two_rectangle_y = [gt_y, gt_y-gt_h, detection_y, detection_y-detection_h]
    two_rectangle_x.sort() #  排序
    two_rectangle_y.sort()
    if (two_rectangle_y[3] - two_rectangle_y[0] >= gt_h+detection_h) | (two_rectangle_x[3] - two_rectangle_x[0] >= gt_w + detection_w):
        return 0
    Intersection = (two_rectangle_x[2] - two_rectangle_x[1]) * (two_rectangle_y[2] - two_rectangle_y[1])
    Union = gt_w*gt_h + detection_w*detection_h - Intersection
    return Intersection / Union

猜你喜欢

转载自blog.csdn.net/qq_34374664/article/details/81395159
今日推荐