{"record":{"id":"80f57c8bf1e7b402","repo":"WZMIAOMIAO/deep-learning-for-image-processing","slug":"all-bounding-boxes-should-have-positive-height-and","errorCode":null,"errorMessage":"All bounding boxes should have positive height and width. Found invalid box {} for target at index {}.","messagePattern":"All bounding boxes should have positive height and width\\. Found invalid box (.+?) for target at index (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pytorch_object_detection/retinaNet/network_files/retinanet.py","lineNumber":490,"sourceCode":"        for img in images:\n            val = img.shape[-2:]\n            assert len(val) == 2\n            original_img_sizes.append((val[0], val[1]))  # h, w\n\n        # transform the input\n        images, targets = self.transform(images, targets)\n\n        # Check for degenerate boxes\n        # TODO: Move this to a function\n        if targets is not None:\n            for target_idx, target in enumerate(targets):\n                boxes = target[\"boxes\"]\n                degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]\n                if degenerate_boxes.any():\n                    # print the first degenerate box\n                    bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]\n                    degen_bb: List[float] = boxes[bb_idx].tolist()\n                    raise ValueError(\"All bounding boxes should have positive height and width.\"\n                                     \" Found invalid box {} for target at index {}.\"\n                                     .format(degen_bb, target_idx))\n\n        # get the features from the backbone\n        features = self.backbone(images.tensors)\n        if isinstance(features, torch.Tensor):\n            features = OrderedDict([(\"0\", features)])\n\n        features = list(features.values())\n\n        # compute the retinanet heads outputs using the features\n        head_outputs = self.head(features)\n\n        # create the set of anchors\n        anchors = self.anchor_generator(images, features)\n\n        losses = {}\n        detections: List[Dict[str, Tensor]] = []","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/blob/1ec3fe6f374fc9969973a61f819de25658595afa/pytorch_object_detection/retinaNet/network_files/retinanet.py#L472-L508","documentation":"During training forward, RetinaNet checks every target for degenerate boxes where x2 <= x1 or y2 <= y1 (non-positive width/height) and raises ValueError identifying the first invalid box and the target index. Degenerate boxes break IoU computation and anchor assignment downstream.","triggerScenarios":"Annotations containing zero-area boxes (x1==x2 or y1==y2), negative width/height from wrong coordinate order (x_min > x_max), or boxes in [cx, cy, w, h] format passed as xyxy; coordinates flipped after resize/clipping transforms.","commonSituations":"Datasets converted between xyxy/xywh formats incorrectly; annotation tools exporting empty boxes for invisible objects; clip-to-image operations that collapse boxes to zero width at image borders; single-point objects (keypoints) labeled as boxes.","solutions":["Sanitize annotations: drop or fix boxes where x2 <= x1 or y2 <= y1 before training.","Verify coordinate format is xyxy (top-left, bottom-right), not xywh or cxcywh.","Clip boxes then re-filter degenerates after clipping to image boundaries.","Assert in the Dataset: assert (boxes[:, 2:] > boxes[:, :2]).all() before returning the target."],"exampleFix":"// before\nboxes = torch.as_tensor(raw_boxes, dtype=torch.float32)\ntarget = {\"boxes\": boxes, \"labels\": labels}\n// after\nboxes = torch.as_tensor(raw_boxes, dtype=torch.float32)\nkeep = (boxes[:, 2:] > boxes[:, :2]).all(dim=1)\nboxes, labels = boxes[keep], labels[keep]  # drop degenerate boxes\ntarget = {\"boxes\": boxes, \"labels\": labels}","handlingStrategy":"validation","validationCode":"import torch\nfor i, t in enumerate(targets):\n    boxes = t[\"boxes\"]\n    if ((boxes[:, 2:] <= boxes[:, :2]).any()):\n        bad = boxes[(boxes[:, 2:] <= boxes[:, :2]).any(dim=1)]\n        print(f\"target {i} has degenerate boxes: {bad.tolist()}\")","typeGuard":"def boxes_are_valid(boxes) -> bool:\n    import torch\n    if not isinstance(boxes, torch.Tensor) or boxes.numel() == 0:\n        return True\n    return bool((boxes[:, 2:] > boxes[:, :2]).all())","tryCatchPattern":"try:\n    outputs = model(images, targets)\nexcept ValueError as e:\n    if \"positive height and width\" in str(e):\n        targets = [sanitize_boxes(t) for t in targets]  # drop degenerate rows\n        outputs = model(images, targets)\n    else:\n        raise","preventionTips":["Sanitize annotations (drop zero/negative-area boxes) at dataset build time.","Confirm the coordinate format is xyxy before inserting into targets.","After clip-to-image, re-filter boxes collapsed to zero area.","Assert box validity in __getitem__ so bad data fails early with context."],"tags":["pytorch","object-detection","annotation","data-quality"],"backgroundTag":"degenerate-bounding-box","analyzedSha":"1ec3fe6f374fc9969973a61f819de25658595afa","analyzedAt":"2026-08-30T09:19:11.901Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}