def extract_keypoints(heatmap, all_keypoints, total_keypoint_num):
heatmap[heatmap < 0.1] = 0
heatmap_with_borders = np.pad(heatmap, [(2, 2), (2, 2)], mode='constant')
heatmap_center = heatmap_with_borders[1:heatmap_with_borders.shape[0]-1, 1:heatmap_with_borders.shape[1]-1]
heatmap_left = heatmap_with_borders[1:heatmap_with_borders.shape[0]-1, 2:heatmap_with_borders.shape[1]]
heatmap_right = heatmap_with_borders[1:heatmap_with_borders.shape[0]-1, 0:heatmap_with_borders.shape[1]-2]
heatmap_up = heatmap_with_borders[2:heatmap_with_borders.shape[0], 1:heatmap_with_borders.shape[1]-1]
heatmap_down = heatmap_with_borders[0:heatmap_with_borders.shape[0]-2, 1:heatmap_with_borders.shape[1]-1]
heatmap_peaks = (heatmap_center > heatmap_left) &\\
(heatmap_center > heatmap_right) &\\
(heatmap_center > heatmap_up) &\\
(heatmap_center > heatmap_down)
heatmap_peaks = heatmap_peaks[1:heatmap_center.shape[0]-1, 1:heatmap_center.shape[1]-1]
keypoints = list(zip(np.nonzero(heatmap_peaks)[1], np.nonzero(heatmap_peaks)[0])) # (w, h)
keypoints = sorted(keypoints, key=itemgetter(0))
suppressed = np.zeros(len(keypoints), np.uint8)
keypoints_with_score_and_id = []
keypoint_num = 0
for i in range(len(keypoints)):
if suppressed[i]:
continue
for j in range(i+1, len(keypoints)):
if math.sqrt((keypoints[i][0] - keypoints[j][0]) ** 2 +
(keypoints[i][1] - keypoints[j][1]) ** 2) < 6:
suppressed[j] = 1
keypoint_with_score_and_id = (keypoints[i][0], keypoints[i][1], heatmap[keypoints[i][1], keypoints[i][0]],
total_keypoint_num + keypoint_num)
keypoints_with_score_and_id.append(keypoint_with_score_and_id)
keypoint_num += 1
all_keypoints.append(keypoints_with_score_and_id)
return keypoint_num
The extract_keypoints
function is responsible for detecting keypoints (e.g., body joints) from a given heatmap. It identifies local peaks in the heatmap, assigns them scores, and associates them with unique IDs. These keypoints are then used in subsequent steps of the pose estimation pipeline.
def extract_keypoints(heatmap, all_keypoints, total_keypoint_num):
heatmap
: A 2D array representing the heatmap for a specific keypoint type (e.g., wrist, elbow). Each value indicates the confidence of a keypoint being present at that location.all_keypoints
: A list to store all detected keypoints, including their coordinates, scores, and IDs.total_keypoint_num
: The total number of keypoints detected so far (used to assign unique IDs).keypoint_num
: The number of keypoints detected in the current heatmap.Thresholding the Heatmap:
heatmap[heatmap < 0.1] = 0
0.1
is set to 0
. This removes low-confidence detections and focuses on stronger peaks.Padding the Heatmap:
heatmap_with_borders = np.pad(heatmap, [(2, 2), (2, 2)], mode='constant')
Extracting Neighboring Regions:
heatmap_center = heatmap_with_borders[1:heatmap_with_borders.shape[0]-1, 1:heatmap_with_borders.shape[1]-1]
heatmap_left = heatmap_with_borders[1:heatmap_with_borders.shape[0]-1, 2:heatmap_with_borders.shape[1]]
heatmap_right = heatmap_with_borders[1:heatmap_with_borders.shape[0]-1, 0:heatmap_with_borders.shape[1]-2]
heatmap_up = heatmap_with_borders[2:heatmap_with_borders.shape[0], 1:heatmap_with_borders.shape[1]-1]
heatmap_down = heatmap_with_borders[0:heatmap_with_borders.shape[0]-2, 1:heatmap_with_borders.shape[1]-1]
Finding Local Peaks:
heatmap_peaks = (heatmap_center > heatmap_left) &\\\\
(heatmap_center > heatmap_right) &\\\\
(heatmap_center > heatmap_up) &\\\\
(heatmap_center > heatmap_down)
heatmap_peaks
) indicating the locations of these peaks.Extracting Keypoint Coordinates:
keypoints = list(zip(np.nonzero(heatmap_peaks)[1], np.nonzero(heatmap_peaks)[0])) # (w, h)
keypoints = sorted(keypoints, key=itemgetter(0))
np.nonzero
.Non-Maximum Suppression:
suppressed = np.zeros(len(keypoints), np.uint8)
keypoints_with_score_and_id = []
keypoint_num = 0
for i in range(len(keypoints)):
if suppressed[i]:
continue
for j in range(i+1, len(keypoints)):
if math.sqrt((keypoints[i][0] - keypoints[j][0]) ** 2 +
(keypoints[i][1] - keypoints[j][1]) ** 2) < 6:
suppressed[j] = 1
Assigning Scores and IDs:
keypoint_with_score_and_id = (keypoints[i][0], keypoints[i][1], heatmap[keypoints[i][1], keypoints[i][0]],
total_keypoint_num + keypoint_num)
keypoints_with_score_and_id.append(keypoint_with_score_and_id)
keypoint_num += 1
(x, y)
are stored.total_keypoint_num
.Storing Keypoints:
all_keypoints.append(keypoints_with_score_and_id)
all_keypoints
list.Returning the Number of Keypoints:
return keypoint_num