Repository: airctic/icevision

Issue:
wrong voc data fixation request (annotation mismatch)
## 🚀 Feature
**Is your feature request related to a problem? Please describe.**

`voc/SegmentationObject/2010_002305.png` has 8 masks but annotation file only has 5. 

```python
# icevision/icevision/tfms/albumentations/albumentations_adapter.py

class Adapter(Transform, Composite):
    ...
    def _filter_attribute(self, v: list):
        if self._keep_mask is None or len(self._keep_mask) == 0:
            return v
        assert len(v) == len(self._keep_mask) # mismatch cause assertion error here
        return [o for o, keep in zip(v, self._keep_mask) if keep]
            )

```

**Describe alternatives you've considered**

I think that assertion should be checked before start learning. 
This is temporal code i used for picking up wrong files.

```python
# icevision/icevision/tfms/albumentations/albumentations_adapter.py

class AlbumentationsMasksComponent(AlbumentationsAdapterComponent):
    ...
    def collect(self, record):
        try:
            masks = self.adapter._filter_attribute(self.adapter._albu_out["masks"])
        except AssertionError as e:
            jpg_path = str(record.as_dict()["common"]["filepath"])
            ann_path = jpg_path.replace("JPEGImages", "Annotations")
            mask_path = jpg_path.replace("JPEGImages", "SegmentationObject")
            raise AttributeError(
                f"Mismatch at annotation file and number of masks. Check or delete 3 files.\n  -{jpg_path}\n  -{ann_path}\n  -{mask_path}"
            )
```

***Mismatch list***
  - voc/2008_005245
  - voc/2009_000455
  - voc/2009_004969
  - voc/2009_005069
  - voc/2011_002863
  - voc/2011_002644



Discussion:
Thanks for taking a look!
Do you want to open a PR about this?
Sounds useful to me :)

Resolving patch:
diff --git a/icevision/tfms/albumentations/albumentations_adapter.py b/icevision/tfms/albumentations/albumentations_adapter.py
--- a/icevision/tfms/albumentations/albumentations_adapter.py
+++ b/icevision/tfms/albumentations/albumentations_adapter.py
@@ -133,7 +133,20 @@ def setup_masks(self, record_component):
         self.adapter._collect_ops.append(CollectOp(self.collect))
 
     def collect(self, record):
-        masks = self.adapter._filter_attribute(self.adapter._albu_out["masks"])
+        try:
+            masks = self.adapter._filter_attribute(self.adapter._albu_out["masks"])
+        except AssertionError:
+            # TODO: messages should be more detailed.
+            img_path = record.as_dict()["common"][
+                "filepath"
+            ]  # ~/.icevision/data/voc/SegmentationObject/2007_000033.png'
+            data_dir = img_path.parents[1]  # ~/.icevision/data/voc'
+            checklist = list(data_dir.glob(f"**/{img_path.stem}.*"))
+            checklist = "".join([f"\n  -{str(path)}" for path in checklist])
+            raise AttributeError(
+                f"Mismatch at annotations with number of masks. Check or delete {len(checklist)} files below. {checklist}"
+            )
+
         masks = MaskArray(np.array(masks))
         self._record_component.set_mask_array(masks)
         # # set masks from the modified masks array


Test patch: