Bisma
Bisma

Reputation: 361

I am getting a ValueError: All bounding boxes should have positive height and width

Hey I am getting the error

ValueError: All bounding boxes should have positive height and width. Found invaid box [264.0, 632.0, 264.0, 633.3333740234375] for target at index 2.
Epoch 1/1
Mini-batch: 1/1220 Loss: 0.1509
Mini-batch: 101/1220 Loss: 0.1201
Mini-batch: 201/1220 Loss: 0.1103
Mini-batch: 301/1220 Loss: 0.1098
Mini-batch: 401/1220 Loss: 0.1076
Mini-batch: 501/1220 Loss: 0.1056
Mini-batch: 601/1220 Loss: 0.1044
Mini-batch: 701/1220 Loss: 0.1035
ValueError Traceback (most recent call last)
in ()
13
14 # Calculate losses
—> 15 loss_dict = model(images, targets)
16 batch_loss = sum(loss for loss in loss_dict.values()) / len(loss_dict)
17

1 frames
/usr/local/lib/python3.6/dist-packages/torchvision/models/detection/generalized_rcnn.py in forward(self, images, targets)
91 raise ValueError(“All bounding boxes should have positive height and width.”
92 " Found invaid box {} for target at index {}."
—> 93 .format(degen_bb, target_idx))
94
95 features = self.backbone(images.tensors)

ValueError: All bounding boxes should have positive height and width. Found invaid box [264.0, 632.0, 264.0, 633.3333740234375] for target at index 2.

I cant find a bounding box that has these coordinates in label csv file. Can anybody please help me out with this.

here is my dataset class

from torch.utils.data import Dataset, DataLoader

Inherit from pytorch Dataset for convenience
class DamageDataset(Dataset):
def __init__(self, dataframe):

    super().__init__()

    self.filename = dataframe['filename'].unique()

    self.df = dataframe

def __len__(self) -> int:

    return len(self.filename)



def __getitem__(self, index: int):

    filename = self.filename[index]

    image = read_image_from_train_folder(filename).astype(np.float32)

    # Scale to [0,1] range expected by the pre-trained model

    image /= 255.0

    # Convert the shape from [h,w,c] to [c,h,w] as expected by pytorch

    image = torch.from_numpy(image).permute(2,0,1)

    

    records = self.df[self.df['filename'] == filename]

    

    boxes = records[['xmin', 'ymin', 'xmax', 'ymax']].values

    classes= records['class'].values

    damage_labels=[]

    damage_dict={

        'D00': 1,

        'D10': 2,

        'D20': 3,

        'D40': 4,

                                                                    

    }

    for label in classes:

      damage_labels.append(damage_dict[label])

   

    boxes = torch.as_tensor(boxes, dtype=torch.float32)

    n_boxes = boxes.shape[0]

    

    # there is only one foreground class, WHEAT

    labels = torch.as_tensor(damage_labels, dtype=torch.float32)

            

    target = {}

    target['boxes'] = boxes

    target['labels'] = labels

    

    return image, target

and here is my train code:

num_epochs = 1

Prepare the model for training
model = model.to(device)

model.train()

for epoch in range(num_epochs):

print("Epoch %i/%i " % (epoch + 1, num_epochs) )

average_loss = 0

for batch_id, (images, targets) in enumerate(train_data_loader):

    # Prepare the batch data

    images, targets = move_batch_to_device(images, targets)

    # Calculate losses

    loss_dict = model(images, targets)

    batch_loss = sum(loss for loss in loss_dict.values()) / len(loss_dict)

    

    # Refresh accumulated optimiser state and minimise losses

    optimizer.zero_grad()

    batch_loss.backward()

can someone help me find out the index of this bounding box so that I can delete it, I have iterated through my dataframe using the code:

for idx, row in merge_labels.iterrows():
if(row[‘xmin’]==264 and row[‘ymin’]== 632 and row[‘xmax’]== 264 and row[‘ymax’]== 633.3333740234375 ):

print(idx)

but it doesnt print any index. thank you

Upvotes: 5

Views: 5422

Answers (2)

Srikanth Reddy
Srikanth Reddy

Reputation: 121

I think you need to check your images bounding boxes. I resolved this issue by making sure that my xmin < xmax and ymin < ymax. if xmin equal to xmax, then it would be a line

Upvotes: 1

Rauf Bhat
Rauf Bhat

Reputation: 136

This is happening because of resize transform applied in fasterRCNN in detection module. If you are explicitly applying a resize operation, the bounding box generated coordinates will change as per the resize definition but if you haven't applied a resize transform and your image min and max size is outsider (800,1333) then a default resize transform is applied.

check the below snippets from the pytorch git repo.

Module: /torchvision/models/detection; Exception generated in generalized_rcnn.py

        degenerate_boxes = boxes[:, 2:] <= boxes[:, :2]
        if degenerate_boxes.any():
            # print the first degenerate box
            bb_idx = torch.where(degenerate_boxes.any(dim=1))[0][0]
            degen_bb: List[float] = boxes[bb_idx].tolist()
            raise ValueError("All bounding boxes should have positive height and width."
                             " Found invalid box {} for target at index {}."
                             .format(degen_bb, target_idx))

Default min max image size; Module: detection/ faster_rcnn

def __init__(self, backbone, num_classes=None,
             # transform parameters
             min_size=800, max_size=1333,
             image_mean=None, image_std=None,
             ............................

transform = GeneralizedRCNNTransform(min_size, max_size, image_mean, image_std)

Target resizing; Module: detection / transform.py

def resize_boxes(boxes, original_size, new_size):
    # type: (Tensor, List[int], List[int]) -> Tensor
    ratios = [
        torch.tensor(s, dtype=torch.float32, device=boxes.device) /
        torch.tensor(s_orig, dtype=torch.float32, device=boxes.device)
        for s, s_orig in zip(new_size, original_size)
    ]
    ratio_height, ratio_width = ratios
    xmin, ymin, xmax, ymax = boxes.unbind(1)

    xmin = xmin * ratio_width
    xmax = xmax * ratio_width
    ymin = ymin * ratio_height
    ymax = ymax * ratio_height
    return torch.stack((xmin, ymin, xmax, ymax), dim=1)

You can fix this by removing/correcting bounding boxes where xmin and xmax or ymin and ymax are equal in the original dataset.

Upvotes: 3

Related Questions