You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从PyTorch姿态估计模型输出张量提取带置信度的关键点?

Hey there! Let's walk through how to convert that model output tensor into usable keypoint coordinates with confidence scores. I’ve worked with this exact HRNet-based pose estimation repo before, so I can break this down clearly.

First, understand your output tensor

Your output shape [1, 16, 64, 56] translates to:

  • 1: Batch size (you’re processing one image at a time)
  • 16: Number of keypoints the model is predicting (this might differ from the 17 you mentioned if the model config was adjusted—double-check your setup if you expect 17!)
  • 64x56: The size of the heatmaps for each keypoint. Each heatmap is a 2D grid where the peak value indicates the confidence of the keypoint being at that location, and the peak’s position maps to the keypoint’s coordinates.

Step 1: Process the heatmaps to get raw coordinates & confidence

Each keypoint’s heatmap has a peak value (confidence) and a corresponding (y, x) position in the heatmap grid. Here’s how to extract those:

First, get your original image dimensions (we’ll need this to map back to pixel coordinates later):

# If your input `img` is a numpy array
original_h, original_w = img.shape[:2]
# If it's a PIL Image
original_h, original_w = img.size[1], img.size[0]

Then process the model output:

model.eval()
img_t = ToTensor()(img).unsqueeze(0)
# Always use torch.no_grad() during inference to save memory
with torch.no_grad():
    out = model(img_t)

# Remove the batch dimension since we're working with one image
heatmaps = out.squeeze(0)  # Shape becomes [16, 64, 56]
num_keypoints = heatmaps.shape[0]

Step 2: Convert heatmap positions to original image pixels

The heatmap is a downscaled version of your input image (HRNet typically outputs heatmaps at 1/4 the input resolution). We’ll map the heatmap coordinates back to your original image’s pixel space, and capture confidence scores:

Basic method (integer coordinates)

This is simple and works well for most cases:

keypoints = []
for kp_idx in range(num_keypoints):
    heatmap = heatmaps[kp_idx]  # Get the heatmap for this keypoint
    # Find the maximum confidence value and its flattened index
    conf, flat_pos = torch.max(heatmap.view(-1), 0)
    # Convert flattened index to (y, x) in the heatmap grid
    hm_y = flat_pos // heatmap.shape[1]
    hm_x = flat_pos % heatmap.shape[1]
    # Map to original image coordinates
    orig_x = float(hm_x * original_w / heatmap.shape[1])
    orig_y = float(hm_y * original_h / heatmap.shape[0])
    # Store the keypoint data
    keypoints.append({
        "keypoint_id": kp_idx,
        "x": orig_x,
        "y": orig_y,
        "confidence": float(conf)
    })

Improved method (sub-pixel accuracy)

For more precise coordinates, you can use sub-pixel interpolation around the heatmap peak. This helps with fine-grained alignment:

def get_subpixel_keypoint(heatmap, original_h, original_w):
    hm_h, hm_w = heatmap.shape
    # Get initial peak position (integer coordinates)
    conf, flat_pos = torch.max(heatmap.view(-1), 0)
    hm_y = flat_pos // hm_w
    hm_x = flat_pos % hm_w
    # Convert to float for interpolation
    hm_x, hm_y = hm_x.float(), hm_y.float()

    # Calculate sub-pixel offset using surrounding pixels
    if 0 < hm_x < hm_w - 1 and 0 < hm_y < hm_h - 1:
        # Compute gradients in x and y directions
        dx = heatmap[hm_y, hm_x + 1] - heatmap[hm_y, hm_x - 1]
        dy = heatmap[hm_y + 1, hm_x] - heatmap[hm_y - 1, hm_x]
        # Update coordinates with sub-pixel adjustment
        hm_x += dx / (2 * (heatmap[hm_y, hm_x + 1] + heatmap[hm_y, hm_x - 1] - 2 * heatmap[hm_y, hm_x]))
        hm_y += dy / (2 * (heatmap[hm_y + 1, hm_x] + heatmap[hm_y - 1, hm_x] - 2 * heatmap[hm_y, hm_x]))

    # Map to original image coordinates
    orig_x = hm_x * original_w / hm_w
    orig_y = hm_y * original_h / hm_h
    return orig_x.item(), orig_y.item(), conf.item()

# Use this function for each keypoint
keypoints = []
for kp_idx in range(num_keypoints):
    x, y, conf = get_subpixel_keypoint(heatmaps[kp_idx], original_h, original_w)
    keypoints.append({
        "keypoint_id": kp_idx,
        "x": x,
        "y": y,
        "confidence": conf
    })

Handling multiple people

Wait—if you’re trying to detect multiple people in an image, this model (HRNet from the repo) is a top-down model. That means you first need to run a person detector (like Faster R-CNN) to get bounding boxes for each person, then crop each person from the original image, resize the crop to the model’s input size, run inference on each crop, and map the keypoints back to the original image using the bounding box coordinates.

For example, if you have a bounding box with top-left corner (x1, y1), width bbox_w, height bbox_h, and you resized the crop to (256, 224) for the model, the mapped coordinates would be:

orig_x = x1 + (crop_keypoint_x * bbox_w / 224)
orig_y = y1 + (crop_keypoint_y * bbox_h / 256)

内容的提问来源于stack exchange,提问作者Ioanna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:12:41