Skip to content

Commit

Permalink
added FaceDetectionData, FaceDetectionPreprocess and FDDBDataSource t…
Browse files Browse the repository at this point in the history
  • Loading branch information
borhanMorphy committed Jul 15, 2021
1 parent ecd92ad commit 02c14c6
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 5 deletions.
7 changes: 6 additions & 1 deletion flash/image/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
ImageClassificationPreprocess,
ImageClassifier,
)
from flash.image.detection import ObjectDetectionData, ObjectDetector # noqa: F401
from flash.image.detection import ( # noqa: F401
ObjectDetectionData,
ObjectDetector,
FaceDetectionData,
FaceDetector
)
from flash.image.embedding import ImageEmbedder # noqa: F401
from flash.image.segmentation import ( # noqa: F401
SemanticSegmentation,
Expand Down
10 changes: 8 additions & 2 deletions flash/image/detection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
from flash.image.detection.data import ObjectDetectionData # noqa: F401
from flash.image.detection.model import ObjectDetector # noqa: F401
from flash.image.detection.data import ( # noqa: F401
ObjectDetectionData,
FaceDetectionData
)
from flash.image.detection.model import ( # noqa: F401
ObjectDetector,
FaceDetector
)
146 changes: 144 additions & 2 deletions flash/image/detection/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
from flash.core.data.data_module import DataModule
from flash.core.data.data_source import DataSource, DefaultDataKeys, DefaultDataSources, FiftyOneDataSource
from flash.core.data.process import Preprocess
from flash.core.utilities.imports import _COCO_AVAILABLE, _FIFTYONE_AVAILABLE, _TORCHVISION_AVAILABLE, lazy_import
from flash.core.utilities.imports import (
_COCO_AVAILABLE,
_FIFTYONE_AVAILABLE,
_TORCHVISION_AVAILABLE,
_FASTFACE_AVAILABLE,
lazy_import
)
from flash.image.data import ImagePathsDataSource
from flash.image.detection.transforms import default_transforms

Expand All @@ -36,6 +42,8 @@
if _TORCHVISION_AVAILABLE:
from torchvision.datasets.folder import default_loader

if _FASTFACE_AVAILABLE:
import fastface as ff

class COCODataSource(DataSource[Tuple[str, str]]):

Expand Down Expand Up @@ -103,7 +111,6 @@ def load_sample(self, sample: Dict[str, Any]) -> Dict[str, Any]:
"size": (h, w),
}
return sample
return sample


class ObjectDetectionFiftyOneDataSource(FiftyOneDataSource):
Expand Down Expand Up @@ -300,3 +307,138 @@ def from_coco(
num_workers=num_workers,
**preprocess_kwargs,
)


class FDDBDataSource(DataSource[Tuple[str, str]]):

def load_data(self, data: Tuple[str, str], dataset: Optional[Any] = None) -> Sequence[Dict[str, Any]]:
source_dir, phase = data
# phase: {train, val, test}
ds = ff.dataset.FDDBDataset(source_dir=source_dir, phase=phase)

data = []

for img_file_path, target in zip(ds.ids, ds.targets):
data.append(
dict(
input=img_file_path,
target=dict(
boxes=target["target_boxes"],
)
)
)

return data

def load_sample(self, sample: Dict[str, Any]) -> Dict[str, Any]:
filepath = sample[DefaultDataKeys.INPUT]
img = default_loader(filepath)
sample[DefaultDataKeys.INPUT] = img
w, h = img.size # WxH
sample[DefaultDataKeys.METADATA] = {
"filepath": filepath,
"size": (h, w),
}
return sample


class FaceDetectionPreprocess(Preprocess):

def __init__(
self,
train_transform: Optional[Dict[str, Callable]] = None,
val_transform: Optional[Dict[str, Callable]] = None,
test_transform: Optional[Dict[str, Callable]] = None,
predict_transform: Optional[Dict[str, Callable]] = None
):
super().__init__(
train_transform=train_transform,
val_transform=val_transform,
test_transform=test_transform,
predict_transform=predict_transform,
data_sources={ # TODO add default detection sources
"fddb": FDDBDataSource()
},
default_data_source=DefaultDataSources.FILES,
)

def get_state_dict(self) -> Dict[str, Any]:
return {**self.transforms}

@classmethod
def load_state_dict(cls, state_dict: Dict[str, Any], strict: bool = False):
return cls(**state_dict)

def default_transforms(self) -> Optional[Dict[str, Callable]]:
return default_transforms()


class FaceDetectionData(DataModule):

preprocess_cls = FaceDetectionPreprocess # TODO

@classmethod
def from_fddb(
cls,
data_folder: Optional[str] = None,
train_data: bool = False,
test_data: bool = False,
val_data: bool = False,
train_transform: Optional[Dict[str, Callable]] = None,
val_transform: Optional[Dict[str, Callable]] = None,
test_transform: Optional[Dict[str, Callable]] = None,
data_fetcher: Optional[BaseDataFetcher] = None,
preprocess: Optional[Preprocess] = None,
val_split: Optional[float] = None,
batch_size: int = 4,
num_workers: Optional[int] = None,
**preprocess_kwargs: Any,
):
"""Creates a :class:`~flash.image.detection.data.FaceDetectionData` object from the given data
folders and corresponding target folders.
Args:
data_folder: The folder containing the `2002`, `2003` ad `FDDB-folds` folders.
val_ann_file: The COCO format annotation file.
train_transform: The dictionary of transforms to use during training which maps
:class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
val_transform: The dictionary of transforms to use during validation which maps
:class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
test_transform: The dictionary of transforms to use during testing which maps
:class:`~flash.core.data.process.Preprocess` hook names to callable transforms.
data_fetcher: The :class:`~flash.core.data.callback.BaseDataFetcher` to pass to the
:class:`~flash.core.data.data_module.DataModule`.
preprocess: The :class:`~flash.core.data.data.Preprocess` to pass to the
:class:`~flash.core.data.data_module.DataModule`. If ``None``, ``cls.preprocess_cls``
will be constructed and used.
val_split: The ``val_split`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.
batch_size: The ``batch_size`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.
num_workers: The ``num_workers`` argument to pass to the :class:`~flash.core.data.data_module.DataModule`.
preprocess_kwargs: Additional keyword arguments to use when constructing the preprocess. Will only be used
if ``preprocess = None``.
Returns:
The constructed data module.
Examples::
data_module = FaceDetectionData.from_fddb(
data_folder="data/",
)
"""

return cls.from_data_source( # TODO
"fddb",
(data_folder, "train") if train_data else None,
(data_folder, "val") if val_data else None,
(data_folder, "test") if test_data else None,
train_transform=train_transform,
val_transform=val_transform,
test_transform=test_transform,
data_fetcher=data_fetcher,
preprocess=preprocess,
val_split=val_split,
batch_size=batch_size,
num_workers=num_workers,
**preprocess_kwargs,
)

0 comments on commit 02c14c6

Please sign in to comment.