Repository: open-mmlab/mmdetection

Issue:
FilterAnnotations does not work properly with PolygonMasks
## Checklist

1. [x] I have searched related issues but cannot get the expected [DONE] (Didn't see similar bug reports)
2. [x] I have read the [FAQ documentation](https://mmdetection.readthedocs.io/en/latest/faq.html) but cannot get the expected help. [DONE] 
3. [x] The bug has not been fixed in the latest version. [DONE] (bug not fixed)

## Describe
When working with datasets in PolygonMasks mode, indexes are transferred incorrectly.

## Reproduction

1. What command or script did you run?

Dataset loader pipeline and use poly2mask=False
```
 [{'type': 'LoadImageFromFile'},
  {'type': 'LoadAnnotations',
   'with_bbox': True,
   'with_mask': True,
   'poly2mask': False},
  {'type': 'FilterAnnotations', 'min_gt_bbox_wh': (5, 5)},
  {'type': 'Collect',
   'keys': ['img', 'gt_bboxes', 'gt_labels', 'gt_masks'],
   'meta_keys': ('filename', 'img_shape')}]
```

2. Did you make any modifications on the code or config? Did you understand what you have modified?
> I didn't modify anything

3. What dataset did you use?
> Custom dataset in coco format.   
> I will attach a simple code to test  

## Environment

1. Please run `python mmdet/utils/collect_env.py` to collect necessary environment information and paste it here.

```

/bin/sh: 1: /usr/local/cuda/bin/nvcc: not found
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
sys.platform: linux
Python: 3.8.10 (default, Mar 15 2022, 12:22:08) [GCC 9.4.0]
CUDA available: True
GPU 0: NVIDIA GeForce RTX 3080 Ti
CUDA_HOME: /usr/local/cuda
NVCC: Not Available
GCC: x86_64-linux-gnu-gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
PyTorch: 1.10.0+cu113
PyTorch compiling details: PyTorch built with:
  - GCC 7.3
  - C++ Version: 201402
  - Intel(R) Math Kernel Library Version 2020.0.0 Product Build 20191122 for Intel(R) 64 architecture applications
  - Intel(R) MKL-DNN v2.2.3 (Git Hash 7336ca9f055cf1bfa13efb658fe15dc9b41f0740)
  - OpenMP 201511 (a.k.a. OpenMP 4.5)
  - LAPACK is enabled (usually provided by MKL)
  - NNPACK is enabled
  - CPU capability usage: AVX2
  - CUDA Runtime 11.3
  - NVCC architecture flags: -gencode;arch=compute_37,code=sm_37;-gencode;arch=compute_50,code=sm_50;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_75,code=sm_75;-gencode;arch=compute_80,code=sm_80;-gencode;arch=compute_86,code=sm_86
  - CuDNN 8.2
  - Magma 2.5.2
  - Build settings: BLAS_INFO=mkl, BUILD_TYPE=Release, CUDA_VERSION=11.3, CUDNN_VERSION=8.2.0, CXX_COMPILER=/opt/rh/devtoolset-7/root/usr/bin/c++, CXX_FLAGS= -Wno-deprecated -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -fopenmp -DNDEBUG -DUSE_KINETO -DUSE_FBGEMM -DUSE_QNNPACK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -DSYMBOLICATE_MOBILE_DEBUG_HANDLE -DEDGE_PROFILER_USE_KINETO -O2 -fPIC -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-result -Wno-unused-local-typedefs -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-psabi -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -fdiagnostics-color=always -faligned-new -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Wno-stringop-overflow, LAPACK_INFO=mkl, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, PERF_WITH_AVX512=1, TORCH_VERSION=1.10.0, USE_CUDA=ON, USE_CUDNN=ON, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=ON, USE_NNPACK=ON, USE_OPENMP=ON, 

TorchVision: 0.11.1+cu113
OpenCV: 4.5.5
MMCV: 1.5.2
MMCV Compiler: GCC 7.3
MMCV CUDA Compiler: 11.3
MMDetection: 2.25.0+

```

2. You may add addition that may be helpful for locating the problem:  
I add dataset and bug example file

## Error traceback
bug have not traceback

## Why did the bug happen?
The PolygonMasks module does not support numpy binary arrays for selection.

## Bug fix
I have already fixed this bug by adding a boolean mask conversion to indexes in the function.  

You need to add the following code to line 627 in the file:
https://github.com/open-mmlab/mmdetection/blob/ca11860f4f3c3ca2ce8340e2686eeaec05b29111/mmdet/datasets/pipelines/loading.py#L627

CODE:

```
keep = np.where(keep == True)[0]
```



## PS...
There is still a small typo in the output of information about the function in line 410 of the file =)  

https://github.com/open-mmlab/mmdetection/blob/ca11860f4f3c3ca2ce8340e2686eeaec05b29111/mmdet/datasets/pipelines/loading.py#L410

CODE to fix:
```
repr_str += f'file_client_args={self.file_client_args})'
```



Discussion:

Resolving patch:
diff --git a/mmdet/datasets/pipelines/loading.py b/mmdet/datasets/pipelines/loading.py
--- a/mmdet/datasets/pipelines/loading.py
+++ b/mmdet/datasets/pipelines/loading.py
@@ -407,7 +407,7 @@ def __repr__(self):
         repr_str += f'with_mask={self.with_mask}, '
         repr_str += f'with_seg={self.with_seg}, '
         repr_str += f'poly2mask={self.poly2mask}, '
-        repr_str += f'poly2mask={self.file_client_args})'
+        repr_str += f'file_client_args={self.file_client_args})'
         return repr_str
 
 
@@ -564,7 +564,7 @@ def __call__(self, results):
 
     def __repr__(self):
         return self.__class__.__name__ + \
-               f'(num_max_proposals={self.num_max_proposals})'
+            f'(num_max_proposals={self.num_max_proposals})'
 
 
 @PIPELINES.register_module()
@@ -625,19 +625,21 @@ def __call__(self, results):
         for t in tests[1:]:
             keep = keep & t
 
+        keep = keep.nonzero()[0]
+
         keys = ('gt_bboxes', 'gt_labels', 'gt_masks')
         for key in keys:
             if key in results:
                 results[key] = results[key][keep]
-        if not keep.any():
+        if keep.size == 0:
             if self.keep_empty:
                 return None
         return results
 
     def __repr__(self):
         return self.__class__.__name__ + \
-               f'(min_gt_bbox_wh={self.min_gt_bbox_wh},' \
-               f'(min_gt_mask_area={self.min_gt_mask_area},' \
-               f'(by_box={self.by_box},' \
-               f'(by_mask={self.by_mask},' \
-               f'always_keep={self.always_keep})'
+            f'(min_gt_bbox_wh={self.min_gt_bbox_wh},' \
+            f'min_gt_mask_area={self.min_gt_mask_area},' \
+            f'by_box={self.by_box},' \
+            f'by_mask={self.by_mask},' \
+            f'always_keep={self.always_keep})'


Test patch:
diff --git a/tests/test_data/test_pipelines/test_loading.py b/tests/test_data/test_pipelines/test_loading.py
--- a/tests/test_data/test_pipelines/test_loading.py
+++ b/tests/test_data/test_pipelines/test_loading.py
@@ -6,7 +6,7 @@
 import numpy as np
 import pytest
 
-from mmdet.core.mask import BitmapMasks
+from mmdet.core.mask import BitmapMasks, PolygonMasks
 from mmdet.datasets.pipelines import (FilterAnnotations, LoadImageFromFile,
                                       LoadImageFromWebcam,
                                       LoadMultiChannelImageFromFiles)
@@ -118,3 +118,15 @@ def test_filter_annotations(target, kwargs):
     if results is not None:
         results = results['gt_bboxes'].shape[0]
     assert results == target
+
+    polygons = [[np.array([2.0, 10.0, 4.0, 10.0, 4.0, 14.0, 2.0, 14.0])],
+                [np.array([2.0, 10.0, 2.1, 10.0, 2.1, 10.1, 2.0, 10.1])]]
+    polygon_masks = PolygonMasks(polygons, 24, 24)
+
+    results = dict(gt_bboxes=bboxes, gt_masks=polygon_masks)
+    results = filter_ann(results)
+
+    if results is not None:
+        results = len(results.get('gt_masks').masks)
+
+    assert results == target