Repository: kornia/kornia

Issue:
Image transforms don't accept empty boxes or keypoints as inputs
### Describe the bug

Image transforms don't accept empty boxes (B, 0, 4) or keypoints (B, 0, 2) as inputs.

### Reproduction steps

```bash
Download panda image: `wget https://tinypng.com/images/social/website.jpg -O panda.jpg`

`
import torch
import kornia.augmentation as K
import torchvision
from kornia.utils import draw_rectangle, tensor_to_image

image = torchvision.io.read_image('panda.jpg').unsqueeze(0).float() / 255.

empty_boxes = torch.empty(1, 0, 4).float()
empty_keypoints = torch.empty(1, 0, 2).float()

aug = K.AugmentationSequential(
  # I tested with different transforms, all raise the same error.
#    K.RandomAffine(360, [0.1, 0.1], [0.7, 1.2], [30., 50.], p=1.0),
   K.RandomVerticalFlip(p=1.0),

   data_keys=["input", "bbox_xyxy", "keypoints"], 
)

tfm_img, tfm_bbox, tfm_keypoints = aug(image, empty_boxes, empty_keypoints)
```


### Expected behavior

To just work or be available to reuse the same kornia transform when images haven't boxes or keypoints associated. 

### Environment

```shell
Kornia 0.6.5
Pytorch 1.9.1+cpu
```


### Additional context


The context is currently, I have a dataset with annotated boxes. Several images don't have, but they are used to train the object detector to reduce false positives. 


Discussion:
What’s the raised error? What do you expect to get in `tfm_boxy and `tfm_keypoints` ?
I expect to get an empty bbox ( size -> (1,0,4) ) and keypoint ( size -> (1, 0, 2) ).

The stacktrace is:
```python
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-119-3368f5f38fa0> in <module>
      2 empty_keypoints = torch.empty(1, 0, 2).float()
      3 
----> 4 tfm_img, tfm_bbox, tfm_keypoints = aug(image, empty_boxes, empty_keypoints)

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
   1049         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1050                 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1051             return forward_call(*input, **kwargs)
   1052         # Do not call functions when jit is used
   1053         full_backward_hooks, non_full_backward_hooks = [], []

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/kornia/augmentation/container/augment.py in forward(self, label, params, data_keys, *args)
    410                 elif isinstance(module, (GeometricAugmentationBase2D, ImageSequential, RandomErasing)) \
    411                         and dcate in DataKey:
--> 412                     input, label = ApplyInverse.apply_by_key(
    413                         input, label, module, param, dcate, extra_args=extra_args)
    414                 elif isinstance(module, (SequentialBase,)):

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/kornia/augmentation/container/utils.py in apply_by_key(cls, input, label, module, param, dcate, extra_args)
    597             # If the input is a tuple with (input, mat) or something else
    598             return (func.apply_trans(input[0], label, module, param, extra_args), *input[1:])  # type: ignore
--> 599         return func.apply_trans(input, label, module=module, param=param, extra_args=extra_args)
    600 
    601     @classmethod

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/kornia/augmentation/container/utils.py in apply_trans(cls, input, label, module, param, extra_args)
    401             _input = cls.pad(_input, padding_size.to(_input))
    402 
--> 403         _input, label = super().apply_trans(_input, label, module, param, extra_args=extra_args)
    404 
    405         # TODO: Filter/crop boxes outside crop (with negative or larger than crop size coords)?

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/kornia/augmentation/container/utils.py in apply_trans(cls, input, label, module, param, extra_args)
    101         # If any inputs need to be transformed.
    102         if mat is not None and to_apply is not None and to_apply.sum() != 0:
--> 103             input[to_apply] = cls.apply_func(mat, input[to_apply])
    104 
    105         return input, label

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/kornia/geometry/bbox.py in transform_bbox(trans_mat, boxes, mode, restore_coordinates)
    474         boxes[..., 3] = boxes[..., 1] + boxes[..., 3]  # y + h
    475 
--> 476     transformed_boxes: torch.Tensor = transform_points(trans_mat, boxes.view(boxes.shape[0], -1, 2))
    477     transformed_boxes = transformed_boxes.view_as(boxes)
    478 

~/PycharmProjects/DLTrain/venv/lib/python3.8/site-packages/kornia/geometry/linalg.py in transform_points(trans_01, points_1)
    182     # We reshape to BxNxD in case we get more dimensions, e.g., MxBxNxD
    183     shape_inp = list(points_1.shape)
--> 184     points_1 = points_1.reshape(-1, points_1.shape[-2], points_1.shape[-1])
    185     trans_01 = trans_01.reshape(-1, trans_01.shape[-2], trans_01.shape[-1])
    186     # We expand trans_01 to match the dimensions needed for bmm

RuntimeError: cannot reshape tensor of 0 elements into shape [-1, 0, 2] because the unspecified dimension size -1 can be any value and is ambiguous
```

Resolving patch:
diff --git a/kornia/augmentation/container/utils.py b/kornia/augmentation/container/utils.py
--- a/kornia/augmentation/container/utils.py
+++ b/kornia/augmentation/container/utils.py
@@ -99,7 +99,7 @@ def apply_trans(
             to_apply = torch.ones(input.shape[0], device=input.device, dtype=input.dtype).bool()
 
         # If any inputs need to be transformed.
-        if mat is not None and to_apply is not None and to_apply.sum() != 0:
+        if mat is not None and to_apply is not None and to_apply.sum() != 0 and input.numel() > 0:
             input[to_apply] = cls.apply_func(mat, input[to_apply])
 
         return input, label


Test patch: