From 34e6ee964d9cae0feb28739b42100963452a46c9 Mon Sep 17 00:00:00 2001
From: Tiago Freitas Pereira <tiagofrepereira@gmail.com>
Date: Wed, 7 Apr 2021 19:07:20 +0200
Subject: [PATCH] Created interface for CASIA-Africa database

Created interface for CASIA-Africa database
---
 bob/bio/face/config/database/casia_africa.py |   9 ++
 bob/bio/face/database/__init__.py            |   2 +
 bob/bio/face/database/casia_africa.py        | 147 +++++++++++++++++++
 bob/bio/face/test/test_databases.py          |  18 ++-
 doc/implemented.rst                          |   1 +
 setup.py                                     |   2 +
 6 files changed, 174 insertions(+), 5 deletions(-)
 create mode 100644 bob/bio/face/config/database/casia_africa.py
 create mode 100644 bob/bio/face/database/casia_africa.py

diff --git a/bob/bio/face/config/database/casia_africa.py b/bob/bio/face/config/database/casia_africa.py
new file mode 100644
index 00000000..1501bdbd
--- /dev/null
+++ b/bob/bio/face/config/database/casia_africa.py
@@ -0,0 +1,9 @@
+from bob.bio.face.database import CasiaAfricaDatabase
+
+# In case protocol is comming from chain loading
+# https://www.idiap.ch/software/bob/docs/bob/bob.extension/stable/py_api.html#bob.extension.config.load
+if "protocol" not in locals():
+    protocol = "ID-V-All-Ep1"
+
+
+database = CasiaAfricaDatabase(protocol=protocol)
diff --git a/bob/bio/face/database/__init__.py b/bob/bio/face/database/__init__.py
index 8450b9f7..b4576b23 100644
--- a/bob/bio/face/database/__init__.py
+++ b/bob/bio/face/database/__init__.py
@@ -14,6 +14,7 @@ from .replaymobile import ReplayMobileBioDatabase
 from .fargo import FargoBioDatabase
 from .meds import MEDSDatabase
 from .morph import MorphDatabase
+from .casia_africa import CasiaAfricaDatabase
 
 # gets sphinx autodoc done right - don't remove it
 
@@ -47,5 +48,6 @@ __appropriate__(
     FargoBioDatabase,
     MEDSDatabase,
     MorphDatabase,
+    CasiaAfricaDatabase,
 )
 __all__ = [_ for _ in dir() if not _.startswith("_")]
diff --git a/bob/bio/face/database/casia_africa.py b/bob/bio/face/database/casia_africa.py
new file mode 100644
index 00000000..833a1858
--- /dev/null
+++ b/bob/bio/face/database/casia_africa.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+# vim: set fileencoding=utf-8 :
+# Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
+
+"""
+  CASIA-Face-Africa: database implementation 
+"""
+
+from bob.bio.base.database import CSVDataset
+from bob.bio.base.database import CSVToSampleLoaderBiometrics
+from bob.bio.face.database.sample_loaders import EyesAnnotations
+from bob.extension import rc
+from bob.extension.download import get_file
+import bob.io.base
+from sklearn.pipeline import make_pipeline
+
+
+class CasiaAfricaDatabase(CSVDataset):
+    """
+    The Casia-Face-Africa dataset is composed of 1133 identities from different ethical groups in Nigeria.
+
+    The capturing locations are: 
+      - Dabai  city  in  Katsina  state
+      - Hotoro  in  Kano  state
+      - Birget  in Kano  state
+      - Gandun  Albasa  in  Kano  state
+      - Sabon  Gari  inKano  state
+      - Kano  State  School  of  Technology
+
+    These locations were strategically selected as they are known to have diverse population of local ethnicities.
+
+    .. warning:: 
+       Only 17 subjects had their images capture in two sessions.
+
+    Images were captured during  daytime  and  night using three different cameras:
+      - C1: Visual Light Camera
+      - C2: Visual Light Camera
+      - C3: NIR camera
+
+
+    This dataset interface implemented the three verificatio protocols: "ID-V-All-Ep1", "ID-V-All-Ep2", and "ID-V-All-Ep3"
+    and they are organized as the following:
+
+    +------------------------------------------------------------------------------------+
+    |                     Dev. Set                                                       |
+    +------------------+----------------------------+------------+----------+------------+
+    |  protocol name   |   Cameras (gallery/probe)  | Identities | Gallery  | Probes     |
+    +==================+============================+============+==========+============+
+    | ID-V-All-Ep1     |      C1/C2                 |   1133     |   2455   |   2426     |
+    +------------------+----------------------------+------------+----------+------------+
+    | ID-V-All-Ep2     |      C1/C3                 |   1133     |   2455   |   1171     |
+    +------------------+----------------------------+------------+----------+------------+
+    | ID-V-All-Ep3     |      C2/C3                 |   1133     |   2466   |   1193     |
+    +------------------+----------------------------+------------+----------+------------+
+
+
+    .. warning::
+        Use the command below to set the path of the real data::
+
+            $ bob config set bob.db.casia-africa.directory [PATH-TO-MEDS-DATA]
+
+
+    .. code-block:: latex
+
+        @article{jawad2020,
+           author  =  {Jawad,  Muhammad  and  Yunlong,  Wang  andCaiyong,  Wang  and  Kunbo,  Zhang  and Zhenan, Sun},
+           title = {CASIA-Face-Africa: A Large-scale African Face Image Database},
+           journal = {IEEE Transactions on Information Forensics and Security},
+           pages = {},
+           ISSN = {},
+           year = {},
+           type = {Journal Article}
+        }
+  
+  
+    Example
+    -------
+
+    Fetching biometric references::
+
+    >>> from bob.bio.face.database import CasiaAfricaDatabase
+    >>> database = CasiaAfricaDatabase(protocol="ID-V-All-Ep1")
+    >>> database.references()
+
+
+    Fetching probes::
+
+    >>> from bob.bio.face.database import CasiaAfricaDatabase
+    >>> database = CasiaAfricaDatabase(protocol="ID-V-All-Ep1")
+    >>> database.probes()
+
+
+    Parameters
+    ----------
+
+    protocol: str
+        One of the database protocols. Options are "ID-V-All-Ep1", "ID-V-All-Ep2" and "ID-V-All-Ep3"
+    """
+
+    def __init__(self, protocol):
+
+        # Downloading model if not exists
+        urls = CasiaAfricaDatabase.urls()
+        filename = get_file(
+            "casia_face_africa.tar.gz",
+            urls,
+            file_hash="324bd69b581477d30606417be8e30d2a",
+        )
+
+        self.annotation_type = "eyes-center"
+        self.fixed_positions = None
+
+        directory = (
+            rc["bob.db.casia-africa.directory"]
+            if rc["bob.db.casia-africa.directory "]
+            else ""
+        )
+
+        super().__init__(
+            filename,
+            protocol,
+            csv_to_sample_loader=make_pipeline(
+                CSVToSampleLoaderBiometrics(
+                    data_loader=bob.io.base.load,
+                    dataset_original_directory=directory,
+                    extension=".jpg",
+                    reference_id_equal_subject_id=False,
+                ),
+                EyesAnnotations(),
+            ),
+        )
+
+    @staticmethod
+    def protocols():
+        # TODO: Until we have (if we have) a function that dumps the protocols, let's use this one.
+        return [
+            "ID-V-All-Ep1",
+            "ID-V-All-Ep2",
+            "ID-V-All-Ep3",
+        ]
+
+    @staticmethod
+    def urls():
+        return [
+            "https://www.idiap.ch/software/bob/databases/latest/casia_face_africa.tar.gz",
+            "http://www.idiap.ch/software/bob/databases/latest/casia_face_africa.tar.gz",
+        ]
diff --git a/bob/bio/face/test/test_databases.py b/bob/bio/face/test/test_databases.py
index b3b31710..c3fb8dca 100644
--- a/bob/bio/face/test/test_databases.py
+++ b/bob/bio/face/test/test_databases.py
@@ -23,9 +23,7 @@ import pytest
 import os
 import bob.bio.base
 from bob.bio.base.test.utils import db_available
-from bob.bio.base.test.test_database_implementations import (
-    check_database,
-)
+from bob.bio.base.test.test_database_implementations import check_database
 import bob.core
 from bob.extension.download import get_file
 
@@ -72,9 +70,9 @@ def test_arface():
     try:
         check_database(database, groups=("dev", "eval"))
     except IOError as e:
-        pytest.skip("The database could not queried; probably the db.sql3 file is missing. Here is the error: '%s'"
+        pytest.skip(
+            "The database could not queried; probably the db.sql3 file is missing. Here is the error: '%s'"
             % e
-
         )
     try:
         _check_annotations(database)
@@ -396,3 +394,13 @@ def test_morph():
 
     assert len(database.references(group="eval")) == 6742
     assert len(database.probes(group="eval")) == 6553
+
+
+def test_casia_africa():
+
+    from bob.bio.face.database import CasiaAfricaDatabase
+
+    database = CasiaAfricaDatabase("ID-V-All-Ep1")
+
+    assert len(database.references()) == 2455
+    assert len(database.probes()) == 2426
diff --git a/doc/implemented.rst b/doc/implemented.rst
index a4de538e..0891df48 100644
--- a/doc/implemented.rst
+++ b/doc/implemented.rst
@@ -13,6 +13,7 @@ Databases
 .. autosummary::
    bob.bio.face.database.ARFaceBioDatabase
    bob.bio.face.database.AtntBioDatabase
+   bob.bio.face.database.CasiaAfricaDatabase
    bob.bio.face.database.MobioDatabase
    bob.bio.face.database.ReplayBioDatabase
    bob.bio.face.database.ReplayMobileBioDatabase
diff --git a/setup.py b/setup.py
index 4fd8cf61..a62ca7be 100644
--- a/setup.py
+++ b/setup.py
@@ -112,6 +112,7 @@ setup(
             "fargo  = bob.bio.face.config.database.fargo:database",
             "meds = bob.bio.face.config.database.meds:database",
             "morph = bob.bio.face.config.database.morph:database",
+            "casia-africa = bob.bio.face.config.database.casia_africa:database",
         ],
         "bob.bio.annotator": [
             "facedetect               = bob.bio.face.config.annotator.facedetect:annotator",
@@ -177,6 +178,7 @@ setup(
             "fargo  = bob.bio.face.config.database.fargo",
             "meds = bob.bio.face.config.database.meds",
             "morph = bob.bio.face.config.database.morph",
+            "casia-africa = bob.bio.face.config.database.casia_africa",
             "resnet50-msceleb-arcface-2021 = bob.bio.face.config.baseline.resnet50_msceleb_arcface_2021",
             "resnet50-vgg2-arcface-2021 = bob.bio.face.config.baseline.resnet50_vgg2_arcface_2021",
             "mobilenetv2-msceleb-arcface-2021 = bob.bio.face.config.baseline.mobilenetv2_msceleb_arcface_2021",
-- 
GitLab