| | |
| | import os.path as osp |
| | import xml.etree.ElementTree as ET |
| |
|
| | from mmengine.dist import is_main_process |
| | from mmengine.fileio import get_local_path, list_from_file |
| | from mmengine.utils import ProgressBar |
| |
|
| | from mmdet.registry import DATASETS |
| | from mmdet.utils.typing_utils import List, Union |
| | from .xml_style import XMLDataset |
| |
|
| |
|
| | @DATASETS.register_module() |
| | class WIDERFaceDataset(XMLDataset): |
| | """Reader for the WIDER Face dataset in PASCAL VOC format. |
| | |
| | Conversion scripts can be found in |
| | https://github.com/sovrasov/wider-face-pascal-voc-annotations |
| | """ |
| | METAINFO = {'classes': ('face', ), 'palette': [(0, 255, 0)]} |
| |
|
| | def load_data_list(self) -> List[dict]: |
| | """Load annotation from XML style ann_file. |
| | |
| | Returns: |
| | list[dict]: Annotation info from XML file. |
| | """ |
| | assert self._metainfo.get('classes', None) is not None, \ |
| | 'classes in `XMLDataset` can not be None.' |
| | self.cat2label = { |
| | cat: i |
| | for i, cat in enumerate(self._metainfo['classes']) |
| | } |
| |
|
| | data_list = [] |
| | img_ids = list_from_file(self.ann_file, backend_args=self.backend_args) |
| |
|
| | |
| | if is_main_process(): |
| | prog_bar = ProgressBar(len(img_ids)) |
| |
|
| | for img_id in img_ids: |
| | raw_img_info = {} |
| | raw_img_info['img_id'] = img_id |
| | raw_img_info['file_name'] = f'{img_id}.jpg' |
| | parsed_data_info = self.parse_data_info(raw_img_info) |
| | data_list.append(parsed_data_info) |
| |
|
| | if is_main_process(): |
| | prog_bar.update() |
| | return data_list |
| |
|
| | def parse_data_info(self, img_info: dict) -> Union[dict, List[dict]]: |
| | """Parse raw annotation to target format. |
| | |
| | Args: |
| | img_info (dict): Raw image information, usually it includes |
| | `img_id`, `file_name`, and `xml_path`. |
| | |
| | Returns: |
| | Union[dict, List[dict]]: Parsed annotation. |
| | """ |
| | data_info = {} |
| | img_id = img_info['img_id'] |
| | xml_path = osp.join(self.data_prefix['img'], 'Annotations', |
| | f'{img_id}.xml') |
| | data_info['img_id'] = img_id |
| | data_info['xml_path'] = xml_path |
| |
|
| | |
| | with get_local_path( |
| | xml_path, backend_args=self.backend_args) as local_path: |
| | raw_ann_info = ET.parse(local_path) |
| | root = raw_ann_info.getroot() |
| | size = root.find('size') |
| | width = int(size.find('width').text) |
| | height = int(size.find('height').text) |
| | folder = root.find('folder').text |
| | img_path = osp.join(self.data_prefix['img'], folder, |
| | img_info['file_name']) |
| | data_info['img_path'] = img_path |
| |
|
| | data_info['height'] = height |
| | data_info['width'] = width |
| |
|
| | |
| | data_info['instances'] = self._parse_instance_info( |
| | raw_ann_info, minus_one=False) |
| | return data_info |
| |
|