关键点检测数据集的标注标准差(关键点归一化因子)统计

根据COCO dataset 官网:COCO - Common Objects in Context, 关键点归一化因子\sigma的计算方法应该是:

关键点检测数据集的标注标准差(关键点归一化因子)统计_第1张图片

 下面的公式是根据网上大部分博客写的,是有问题的。于2021/12/11更正。

---------------------------------------------分割线,下面内容有些问题------------------------------------------------

       人体姿态估计的评估指标为AP,其类似于目标检测领域的AP,只不过将iou替换为oks。oks(object keypoint similarity),是目前常用的人体骨骼关键点检测算法的评价指标,目的就是为了计算真值和预测人体关键点的相似度。

关键点检测数据集的标注标准差(关键点归一化因子)统计_第2张图片       其中\sigma:表示关键点归一化因子,这个因子是通过对所有的样本集中的关键点由人工标注与真实值存在的标准差,\sigma越大表示此类型的关键点越难标注。

       \sigma的计算方法:

关键点检测数据集的标注标准差(关键点归一化因子)统计_第3张图片

       下面是根据上述公式写的代码,背景:自己创建的关键点数据集(包含多个类别,不同类别下的关键点定义的数量不同)。两个path下分别为人工标注与真实值的annotation的json文件(labelme生成),num列表存储的是不同类别的关键点数量。标注标准差\sigma最后存储在sigma列表中。

import os                                                                                                               
import numpy as np                                                                                                      
import json                                                                                                             
import codecs                                                                                                           
import math                                                                                                             
                                                                                                                        
class MyEncoder(json.JSONEncoder):                                                                                      
    def default(self, obj):                                                                                             
        if isinstance(obj, np.integer):                                                                                 
            return int(obj)                                                                                             
        elif isinstance(obj, np.floating):                                                                              
            return float(obj)                                                                                           
        elif isinstance(obj, np.ndarray):                                                                               
            return obj.tolist()                                                                                         
        else:                                                                                                           
            return super(MyEncoder, self).default(obj)                                                                  
                                                                                                                        
                                                                                                                        
path = '../已核'                                                                                
path_matched = '../ori'                                                                       
num = [27, 5, 10, 6, 4, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1]                                                                
a = 0                                                                                                                   
all = []                                                                                                                
all_avg = []                                                                                                            
a = [0,1,2,3,5,6,7,9,11,12,13,14,15,17,19,22]                                                                           
for r,t in enumerate(a):                                                                                                
    path1 = path + '/' + str(t + 1)                                                                                     
    path2 = path_matched + '/' + str(t + 1)                                                                             
    list_ori = os.listdir(path1)                                                                                        
    list_matched = os.listdir(path2)                                                                                    
    class_list = []                                                                                                     
    for item1 in list_ori:                                                                                              
        # 如果该文件以json结尾                                                                                                  
        if(item1.split('.')[1] == 'json'):                                                                              
            path_ori = path1 + '/' + item1                                                                              
            data1 = codecs.open(path_ori, 'r', 'gbk')                                                                   
            data1 = json.load(data1)                                                                                    
            anno1 = data1["shapes"]                                                                                     
            w = data1["imageWidth"]                                                                                     
            h = data1["imageHeight"]                                                                                    
                                                                                                                        
                                                                                                                        
            if(item1 in list_matched):                                                                                  
                path_matched_json = path2 + '/' + item1                                                                 
                data2 = codecs.open(path_matched_json, 'r', 'gbk')                                                      
                data2 = json.load(data2)                                                                                
                anno2 = data2["shapes"]                                                                                 
                                                                                                                        
                # 将本json文件(对应一张图片)下的所有点保存在一个list中                                                                       
                l1 = [[]] * num[r]                                                                                      
                for shape in anno1:                                                                                     
                    i = int(shape["label"])                                                                             
                    if(i != 90):                                                                                        
                        l1[i] = shape["points"][0]                                                                      
                    else:                                                                                               
                        w = abs(shape["points"][0][0] - shape["points"][1][0])                                          
                        h = abs(shape["points"][0][1] - shape["points"][1][1])                                          
                                                                                                                        
                l2 = [[]] * num[r]                                                                                      
                for shape in anno2:                                                                                     
                    i = int(shape["label"])                                                                             
                    if(i != 90):                                                                                        
                        l2[i] = shape["points"][0]                                                                      
                                                                                                                        
                # 单张图片在本类下(一共23类)所有点的d/S的值                                                                              
                ds = [[]] * num[r]                                                                                      
                for i,j in enumerate(l1):                                                                               
                    j_matched = l2[i]                                                                                   
                    d = math.pow(j[0] - j_matched[0], 2) + math.pow(j[1] - j_matched[1], 2)                             
                    ds[i] = math.sqrt(d / (w * h))                                                                      
                                                                                                                        
            class_list.append(ds)                                                                                       
                                                                                                                        
    all.append(class_list)                                                                                              
    sum = [0] * int(num[r])                                                                                             
    for l in class_list:                                                                                                
        for i,j in enumerate(l):                                                                                        
            sum[i] = sum[i] + j                                                                                         
    avg = []                                                                                                            
    l = len(class_list)                                                                                                 
    avg = [i / l for i in sum]                                                                                          
    all_avg.append(avg)                                                                                                 
                                                                                                                        
sigma = []                                                                                                              
for i in range(len(all)):                                                                                               
    # 每一类的统计的E(d/s)                                                                                                     
    temp_avg = all_avg[i]                                                                                               
    # 每一类的所有人的数据,双层列表                                                                                                   
    temp_people = all[i]                                                                                                
    # 每一类的人数                                                                                                            
    lens = len(temp_people)                                                                                             
    temp_ds_e = []                                                                                                      
    for k in temp_people:                                                                                               
        temp_ds_e_per_person = []                                                                                       
        for m,n in enumerate(k):                                                                                        
            # (d/s - E(d/s))^2                                                                                          
            oo = math.pow(n - temp_avg[m], 2)                                                                           
            temp_ds_e_per_person.append(oo)                                                                             
        temp_ds_e.append(temp_ds_e_per_person)                                                                          
                                                                                                                        
    sum_1 = [0] * len(temp_avg)                                                                                         
    for l in temp_ds_e:                                                                                                 
        for o,p in enumerate(l):                                                                                        
            sum_1[o] = sum_1[o] + p                                                                                     
    avg_1 = []                                                                                                          
    avg_1 = [math.sqrt(v / lens) for v in sum_1]                                                                        
                                                                                                                        
    for sigma_i in avg_1:                                                                                               
        sigma.append(sigma_i)                                                                                           
print(len(sigma))                                                                                                       
print(sigma)                                                                                                            

你可能感兴趣的:(计算机视觉,关键点检测,COCO,python,深度学习,计算机视觉)