订阅
纠错
加入自媒体

如何使用Python分析姿态估计数据集COCO?

2021-01-16 09:50
磐创AI
关注

   # 遍历所有图像
   for img_id, img_fname, w, h, meta in get_meta(coco):
       images_data.append({
           'image_id': int(img_id),
           'path': img_fname,
           'width': int(w),
           'height': int(h)
       })
       
       # 遍历所有元数据
       for m in meta:
           persons_data.append({
               'image_id': m['image_id'],
               'is_crowd': m['iscrowd'],
               'bbox': m['bbox'],
               'area': m['area'],
               'num_keypoints': m['num_keypoints'],
               'keypoints': m['keypoints'],
           })
           
   # 创建带有图像路径的数据帧
   images_df = pd.DataFrame(images_data)
   images_df.set_index('image_id', inplace=True)
   
   # 创建与人相关的数据帧
   persons_df = pd.DataFrame(persons_data)
   persons_df.set_index('image_id', inplace=True)
   return images_df, persons_df
我们使用get_meta函数构造两个数据帧—一个用于图像路径,另一个用于人的元数据。在一个图像中可能有多个人,因此是一对多的关系。在下一步中,我们合并两个表(left join操作)并将训练集和验证集组合,另外,我们添加了一个新列source,值为0表示训练集,值为1表示验证集。这样的信息是必要的,因为我们需要知道应该在哪个文件夹中搜索图像。如你所知,这些图像位于两个文件夹中:train2017/和val2017/images_df, persons_df = convert_to_df(train_coco)
train_coco_df = pd.merge(images_df, persons_df, right_index=True, left_index=True)
train_coco_df['source'] = 0
images_df, persons_df = convert_to_df(val_coco)
val_coco_df = pd.merge(images_df, persons_df, right_index=True, left_index=True)
val_coco_df['source'] = 1
coco_df = pd.concat([train_coco_df, val_coco_df], ignore_index=True)
最后,我们有一个表示整个COCO数据集的数据帧。图像中有多少人现在我们可以执行第一个分析。COCO数据集包含多个人的图像,我们想知道有多少图像只包含一个人。代码如下:# 计数
annotated_persons_df = coco_df[coco_df['is_crowd'] == 0]
crowd_df = coco_df[coco_df['is_crowd'] == 1]
print("Number of people in total: " + str(len(annotated_persons_df)))
print("Number of crowd annotations: " + str(len(crowd_df)))
persons_in_img_df = pd.DataFrame({
   'cnt': annotated_persons_df['path'].value_counts()
})
persons_in_img_df.reset_index(level=0, inplace=True)
persons_in_img_df.rename(columns = {'index':'path'}, inplace = True)
# 按cnt分组,这样我们就可以在一张图片中得到带有注释人数的数据帧
persons_in_img_df = persons_in_img_df.groupby(['cnt']).count()
# 提取数组
x_occurences = persons_in_img_df.index.values
y_images = persons_in_img_df['path'].values
# 绘图
plt.bar(x_occurences, y_images)
plt.title('People on a single image ')
plt.xticks(x_occurences, x_occurences)
plt.xlabel('Number of people in a single image')
plt.ylabel('Number of images')
plt.show()
结果图表:

如你所见,大多数COCO图片都包含一个人。但也有相当多的13个人的照片,让我们举几个例子:

好吧,甚至有一张图片有19个注解(非人群):

这个图像的顶部区域不应该标记为一个人群吗?是的,应该,但是,我们有多个没有关键点的边界框!这样的注释应该像对待人群一样对待,这意味着它们应该被屏蔽。在这张图片中,只有中间的3个方框有一些关键点。让我们来优化查询,以获取包含有/没有关键点的人图像的统计信息,以及有/没有关键点的人的总数:annotated_persons_nokp_df = coco_df[(coco_df['is_crowd'] == 0) & (coco_df['num_keypoints'] == 0)]
annotated_persons_kp_df = coco_df[(coco_df['is_crowd'] == 0) & (coco_df['num_keypoints'] > 0)]
print("Number of people (with keypoints) in total: " +
       str(len(annotated_persons_kp_df)))
print("Number of people without any keypoints in total: " +
       str(len(annotated_persons_nokp_df)))
persons_in_img_kp_df = pd.DataFrame({
   'cnt': annotated_persons_kp_df[['path','source']].value_counts()
})
persons_in_img_kp_df.reset_index(level=[0,1], inplace=True)
persons_in_img_cnt_df = persons_in_img_kp_df.groupby(['cnt']).count()
x_occurences_kp = persons_in_img_cnt_df.index.values
y_images_kp = persons_in_img_cnt_df['path'].values
f = plt.figure(figsize=(14, 8))
width = 0.4
plt.bar(x_occurences_kp, y_images_kp, width=width, label='with keypoints')
plt.bar(x_occurences + width, y_images, width=width, label='no keypoints')
plt.title('People on a single image ')
plt.xticks(x_occurences + width/2, x_occurences)
plt.xlabel('Number of people in a single image')
plt.ylabel('Number of images')
plt.legend(loc = 'best')
plt.show()
现在我们可以看到区别是明显的。

虽然COCO官方页面上描述有25万人拥有关键点,而我们只有156165个这样的例子。他们可能应该删除了“带关键点”这几个字。添加额外列一旦我们将COCO转换成pandas数据帧,我们就可以很容易地添加额外的列,从现有的列中计算出来。我认为最好将所有的关键点坐标提取到单独的列中,此外,我们可以添加一个具有比例因子的列。特别是,关于一个人的边界框的规模信息是非常有用的,例如,我们可能希望丢弃所有太小规模的人,或者执行放大操作。为了实现这个目标,我们使用Python库sklearn中的transformer对象。一般来说,sklearn transformers是用于清理、减少、扩展和生成数据科学模型中的特征表示的强大工具。我们只会用一小部分的api。代码如下:from sklearn.base import BaseEstimator, TransformerMixin
class AttributesAdder(BaseEstimator, TransformerMixin):
   def __init__(self, num_keypoints, w_ix, h_ix, bbox_ix, kp_ix):
       """
       :param num_keypoints: 关键点的数量
       :param w_ix: 包含图像宽度的列索引
       :param h_ix: 包含图像高度的列索引
       :param bbox_ix: 包含边框数据的列索引
       :param kp_ix: 包含关键点数据的列索引
       """
       self.num_keypoints = num_keypoints
       self.w_ix = w_ix
       self.h_ix = h_ix
       self.bbox_ix = bbox_ix
       self.kp_ix = kp_ix
       
   def fit(self, X, y=None):
       return self
     
   def transform(self, X):
     
       # 检索特定列
       
       w = X[:, self.w_ix]
       h = X[:, self.h_ix]
       bbox = np.array(X[:, self.bbox_ix].tolist())  # to matrix
       keypoints = np.array(X[:, self.kp_ix].tolist()) # to matrix

<上一页  1  2  3  下一页>  
声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

    人工智能 猎头职位 更多
    扫码关注公众号
    OFweek人工智能网
    获取更多精彩内容
    文章纠错
    x
    *文字标题:
    *纠错内容:
    联系邮箱:
    *验 证 码:

    粤公网安备 44030502002758号