open-mmlab/mmdetection · error · KeyError
In the image with ID {} the following segment IDs {} are pre
Error message
In the image with ID {} the following segment IDs {} are presented in JSON and not presented in PNG. What it means
Inverse consistency check of error 68: every id listed in segments_info must appear as a nonzero label in the prediction PNG. Leftover JSON ids not found in the PNG raise KeyError listing the missing ids.
Source
Thrown at mmdet/evaluation/functional/panoptic_utils.py:104
labels, labels_cnt = np.unique(pan_pred, return_counts=True)
for label, label_cnt in zip(labels, labels_cnt):
if label not in pred_segms:
if label == VOID:
continue
raise KeyError(
'In the image with ID {} segment with ID {} is '
'presented in PNG and not presented in JSON.'.format(
gt_ann['image_id'], label))
pred_segms[label]['area'] = label_cnt
pred_labels_set.remove(label)
if pred_segms[label]['category_id'] not in categories:
raise KeyError(
'In the image with ID {} segment with ID {} has '
'unknown category_id {}.'.format(
gt_ann['image_id'], label,
pred_segms[label]['category_id']))
if len(pred_labels_set) != 0:
raise KeyError(
'In the image with ID {} the following segment IDs {} '
'are presented in JSON and not presented in PNG.'.format(
gt_ann['image_id'], list(pred_labels_set)))
# confusion matrix calculation
pan_gt_pred = pan_gt.astype(np.uint64) * OFFSET + pan_pred.astype(
np.uint64)
gt_pred_map = {}
labels, labels_cnt = np.unique(pan_gt_pred, return_counts=True)
for label, intersection in zip(labels, labels_cnt):
gt_id = label // OFFSET
pred_id = label % OFFSET
gt_pred_map[(gt_id, pred_id)] = intersection
# count all matched pairs
gt_matched = set()
pred_matched = set()
for label_tuple, intersection in gt_pred_map.items():View on GitHub (pinned to cfd5d3a985)
Solutions
- Write the PNG and segments_info from the same final segment set (single source of truth)
- Use int32-safe PNG encoding so large ids are not truncated
- Filter both JSON and PNG consistently when applying min-area/size thresholds
Example fix
# before
# JSON ids {1,2,3}; PNG contains {1,2} only
# after
result_panpng[seg_mask] = seg['id'] # write every seg in segments_info to PNG
json.dump({'segments_info': segments_info, ...}, f) Defensive patterns
Strategy: validation
Validate before calling
png_ids = set(np.unique(pan_png)) - {0}
json_ids = {s['id'] for s in segments_info}
assert png_ids == json_ids, f'missing in PNG: {json_ids - png_ids}' Try / catch
try:
pq_compute_single_core(...)
except KeyError as e:
if 'not presented in PNG' in str(e):
raise ValueError('Regenerate PNG so all JSON segment ids are painted') from e
raise Prevention
- Paint every segments_info id into the PNG, no filtering after JSON creation
- Use int32 arrays for id maps to avoid truncation
- Apply min-area filters before writing either artifact
When it happens
Trigger: segments_info entries kept for segments that were dropped, merged, or fully suppressed when writing the PNG; tiny segments lost to resizing; empty masks encoded as absent.
Common situations: Postprocessing that filters PNG masks (e.g. min-area threshold) without updating JSON; PNG encoding that maps some ids to 0 due to dtype overflow (ids > 65535 in uint16).
Related errors
- In the image with ID {} segment with ID {} is presented in P
- panopticapi is not installed, please install it by: pip inst
- In the image with ID {} segment with ID {} has unknown categ
- Please run accumulate() first
- Package lvis is not installed. Please run "pip install git+h
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/8df239faf4b9cbde.
Report an issue: GitHub.