前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关键点估计之 PCK, PCKh, PDJ 评价度量

关键点估计之 PCK, PCKh, PDJ 评价度量

作者头像
AIHGF
发布2019-02-18 15:09:29
3.4K0
发布2019-02-18 15:09:29
举报
文章被收录于专栏:AIUAIAIUAI

原文 - https://www.aiuai.cn/aifarm449.html - AIUAI

关键点估计 - 人体关键点(姿态估计) 和服饰关键点(FashionAI/DeepFashion). 单人关键点估计,评测.

1. PCK - Percentage of Correct Keypoints

关键点正确估计的比例 计算检测的关键点与其对应的groundtruth间的归一化距离小于设定阈值的比例(the percentage of detections that fall within a normalized distance of the ground truth).

FLIC 中是以躯干直径(torso size) 作为归一化参考. MPII 中是以头部长度(head length) 作为归一化参考,即 PCKh.

代码语言:javascript
复制
function eval_pck(pred, joints, symmetry_joint_id, joint_name, name)
% PCK 的实现
% torso height: || left_shoulder - right hip ||
% symmetry_joint_id: 具有对称关系的关键点 ID
% joint_name: 具有对称关系的关键点名字

range = 0:0.01:0.1;
show_joint_ids = (symmetry_joint_id >= 1:numel(symmetry_joint_id));

% compute distance to ground truth joints
dist = get_dist_pck(pred, joints(1:2,:,:));

% 计算 PCK
pck_all = compute_pck(dist,range);
pck = pck_all(end, :);
pck(1:end-1) = (pck(1:end-1) + pck(symmetry_joint_id))/2;

% 可视化结果
pck = [pck(show_joint_ids) pck(end)];
fprintf('------------ PCK Evaluation: %s -------------\n', name);
fprintf('Parts '); fprintf('& %s ', joint_name{:}); fprintf('& Mean\n');
fprintf('PCK   '); fprintf('& %.1f  ', pck); fprintf('\n');

% -------------------------------------------------------------------------
function dist = get_dist_pck(pred, gt)
assert(size(pred,1) == size(gt,1) && size(pred,2) == size(gt,2) && size(pred,3) == size(gt,3));

dist = nan(1,size(pred, 2), size(pred,3));

for imgidx = 1:size(pred,3)
  % torso diameter 躯干直径
  if size(gt, 2) == 14
    refDist = norm(gt(:,10,imgidx) - gt(:,3,imgidx));
  elseif size(gt, 2) == 10 % 10 joints FLIC
    refDist = norm(gt(:,7,imgidx) - gt(:,6,imgidx));
  elseif size(gt, 2) == 11 % 11 joints FLIC
    refDist = norm(gt(:,4,imgidx) - gt(:,11,imgidx));
  else
    error('Number of joints should be 14 or 10 or 11');
  end

  % 预测的关键点与 gt 关键点的距离
  dist(1,:,imgidx) = sqrt(sum((pred(:,:,imgidx) - gt(:,:,imgidx)).^2,1))./refDist;

end

% -------------------------------------------------------------------------
function pck = compute_pck(dist,range)
pck = zeros(numel(range),size(dist,2)+1);

for jidx = 1:size(dist,2)
  % 计算每个设定阈值的 PCK
  for k = 1:numel(range)
    pck(k,jidx) = 100*mean(squeeze(dist(1,jidx,:)) <= range(k));
  end
end

% 计算平均 PCK
for k = 1:numel(range)
  pck(k,end) = 100*mean(reshape(squeeze(dist(1,:,:)),size(dist,2)*size(dist,3),1) <= range(k));
end

输出结果如下:

代码语言:javascript
复制
------------ PCK Evaluation: Single_People -------------
Parts & Ankle & Knee & Hip & Wris & Elbo & Shou & Head & Mean
PCK   & 93.2  & 88.3  & 70.4  & 92.1  & 92.6  & 94.6  & 95.9  & 89.6

1.1 PCKh

代码语言:javascript
复制
% 计算 head 的长度
headSize = getHeadSizeAll(annolist_test_flat(single_person_test_flat == 1));

% 计算预测的关键点与 gt 关键点间的归一化距离
dist = getDistPCKh(pred,gt,headSize);

% 计算 PCKh
pck = computePCK(dist,range);


function headSizeAll = getHeadSizeAll(annolist)
headSizeAll = nan(length(annolist),1);
for imgidx = 1:length(annolist)
    rect = annolist(imgidx).annorect;
    headSizeAll(imgidx) =  util_get_head_size(rect);
end
end

function headSize = util_get_head_size(rect)
SC_BIAS = 0.6; % 0.8*0.75
headSize = SC_BIAS*norm([rect.x2 rect.y2] - [rect.x1 rect.y1]); # head 的两个点间的距离
end

function dist = getDistPCKh(pred,gt,refDist)
assert(size(pred,1) == size(gt,1) && size(pred,2) == size(gt,2) && size(pred,3) == size(gt,3));
assert(size(refDist,1) == size(gt,3));

dist = nan(1,size(pred,2),size(pred,3));
for imgidx = 1:size(pred,3)
    % pred joints 与 gt joints 的归一化距离
    dist(1,:,imgidx) = sqrt(sum((pred(:,:,imgidx) - gt(:,:,imgidx)).^2,1))./refDist(imgidx);
end

function pck = computePCK(dist,range)
pck = zeros(numel(range),size(dist,2)+2);
for jidx = 1:size(dist,2)
    % 计算各阈值的 PCK
    for k = 1:numel(range)
        d = squeeze(dist(1,jidx,:));
        % dist is NaN if gt is missing; ignore dist in this case
        pck(k,jidx) = 100*mean(d(~isnan(d))<=range(k));
    end
end

% 计算上半身关键点的平均 PCK
for k = 1:numel(range)
    d = reshape(squeeze(dist(1,7:12,:)),6*size(dist,3),1);
    pck(k,end-1) = 100*mean(d(~isnan(d))<=range(k));
end

% 计算全身关键点的 PCK
for k = 1:numel(range)
    d = reshape(squeeze(dist(1,:,:)),size(dist,2)*size(dist,3),1);
    pck(k,end) = 100*mean(d(~isnan(d))<=range(k));
end
end

2. PDJ - Percentage of Detected Joints

检测到的关键点比例.

代码语言:javascript
复制
function [accs, range] = eval_pdj(pred, joints, reference_joints_pair, symmetry_joint_id, joint_name, eval_name)
% 设定选定的参考点:reference_joints_pair = [3, 10];     % 右肩点到左臀点
% symmetry_joint_id: 具有对称关系的关键点 ID
assert(numel(reference_joints_pair) == 2);
show_joint_ids = find(symmetry_joint_id >= 1:numel(symmetry_joint_id)); 
range = 0:0.01:0.5;

num = size(pred, 3);
assert(num >= 1);
% the number of joints
joint_n = size(joints, 2);

scale = zeros(1, num);
for ii = 1:num
  scale(ii) = norm( joints(:,reference_joints_pair(1), ii) - joints(:,reference_joints_pair(2), ii) );
  %scale(ii) = 100;
end

dists = zeros(num, joint_n);
for ii = 1:num
  dists(ii,:) = sqrt(sum( (pred(:, :, ii) - joints(:,:,ii)).^2, 1 ));
  dists(ii,:) = dists(ii,:) / scale(ii);
end

accs = zeros(numel(range), joint_n);
for ii = 1:numel(range)
  accs(ii,:) = mean(dists <= range(ii),1);
end

accs = (accs + accs(:,symmetry_joint_id)) / 2;
accs = accs(:, show_joint_ids);
% print
fprintf('-------------- PDJ Evaluation ---------------\n')
fprintf('Joints    '); fprintf('& %s ', joint_name{:}); fprintf('\n');
sample_pdj_thresholds = [0.1, 0.2, 0.3, 0.4];
for ii = 1:length(sample_pdj_thresholds)
  t = sample_pdj_thresholds(ii);
  idx = (range == t);
  fprintf('PDJ@%.2f  ', t); fprintf('& %.1f ', accs(idx,:)*100); fprintf('\n');
end

% plot
line_width = 2;
p_color = {'g','y','b','r','c','k','m'};

% visualize
figure; hold on; grid on;
for ii = 1:numel(show_joint_ids)
  plot(range, accs(:, ii), p_color{mod(ii, numel(p_color))+1}, 'linewidth', line_width);
end
leg_str = cell(numel(show_joint_ids), 1);
for ii = 1:numel(show_joint_ids)
  leg_str{ii} = sprintf('%s', joint_name{ii});
end
h_leg = legend(leg_str, 'FontSize', 12);
set(h_leg, 'location', 'southeast', 'linewidth', 1);

axis([range(1),range(end), 0, 1]);
set(gca,'ytick', 0:0.1:1);
set(gca, 'linewidth', 1);

% --- titles
xlabel('Normalized  Threshold') % x-axis label
ylabel('Detection Rate') % y-axis label

title([eval_name ' PDJ']);
hold off;

输出结果为:

代码语言:javascript
复制
-------------- PDJ Evaluation ---------------
Joints    & Ankle & Knee & Hip & Wris & Elbo & Shou & Head 
PDJ@0.10  & 93.3 & 87.6 & 66.4 & 91.8 & 92.6 & 95.5 & 96.1 
PDJ@0.20  & 97.5 & 94.7 & 93.4 & 96.8 & 97.9 & 98.8 & 99.1 
PDJ@0.30  & 97.9 & 95.7 & 97.6 & 97.8 & 98.4 & 99.1 & 99.2 
PDJ@0.40  & 98.1 & 96.1 & 98.4 & 98.1 & 98.6 & 99.2 & 99.2 
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. PCK - Percentage of Correct Keypoints
    • 1.1 PCKh
    • 2. PDJ - Percentage of Detected Joints
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档