mroi-fd 1.0.0.post3
 Face detection wrapper using hybrid margin-based region of interest (MROI) approach."
Requires Python: >=3.7.0

## Automatic Installation

You can install the hybrid MROI face detection wrapper using `pip`:

```
pip install mroi-fd
```

## Manual Installation

This project is developed and tested on python version `3.7.4`. Please check
your python version using `python --version`. If your system has a different
python version, you may want to consider using
[pyenv](https://github.com/pyenv/pyenv) (See [Using pyenv](#using-pyenv-linux-windows-macos))

First, clone and `cd` into the repository:

```
git clone https://gitlab.com/ailabuser/bacha_hybrid_mroi_face_detection
cd bacha_hybrid_mroi_face_detection
```

### On Windows:

Create a python virtual environment:

```
mkvirtualenv venv
```

Activate the virtual environment (`deactivate` to deactivate the virtual
environment):

```
workon venv
```

Install all the required dependencies while still having the virtual environment
active:

```
pip install -r requirements.txt
```


### On Linux:

Create a python virtual environment:

```
virtualenv -p /usr/bin/python3 venv
```

Activate the virtual environment (`deactivate` to deactivate the virtual
environment):

```
source venv/bin/activate
```

Install all the required dependencies while still having the virtual environment
active:

```
pip install -r requirements.txt
```

### Using pyenv (Linux, Windows, MacOS)

If your python version is not 3.7.4, you may want to use
[pyenv](https://github.com/pyenv/pyenv). After you have installed `pyenv`,
install the specific python version. On Linux, this can be done by running the
following command:

```
env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.4
```

Then, create a virtual environment:

```
pyenv virtualenv 3.7.4 bacha_mroi_face_detection
```

You can activate the virtual environment using `pyenv` like so:

```
pyenv activate bacha_mroi_face_detection
```

## Description 

The face detection technique used hybrid margin-based region of interest (MROI)
approach. It is hybrid in the sense that the implementation runs one main
routine to detect a face, but switch to an escape routine when the main routine
fails. Using MROI increase the face detection speed by having the selected face
detection algorithm to only consider a sub-region (where a face was previously
detected) instead of the full frame.

There are three pre-defined selection of main routines available for you to use:

1. Haar cascade classifier
2. Joint cascade
3. Multi-task Convolutional Neural Network (MTCNN)

When the main routine failed to detect a face, the implementation switch to the
escape routine which runs template matching algorithm.

# Example

## Using the hybrid MROI for your face detection implementation

In order to use your face detection algorithm with the hybrid MROI face
detector, you need to create a subclass which inherit the `FaceDetector` class,
and override its `detect` method. The implementation requires the`detect`
method to return either a face ROI or `None`; otherwise, the hybrid MROI face
detector may fail.

Here's an example, in which we use a [python implementation of
MTCNN](https://pypi.org/project/mtcnn/):

```python
import cv2
from mtcnn.mtcnn import MTCNN
from mroi_fd import FaceDetector

class MROI_MTCNN(FaceDetector):

    def __init__(self):

    	# The main routine face detector object used to detect faces.
        fd_obj = MTCNN()

	# Initialize using base class constructor. We pass the face detector
	# object (fd_obj) and use the MROI with fixed-margin approach with
	# a template matching escape routine.
        super().__init__(fd_obj, mode=FaceDetector.FMTM)

    @staticmethod
    def detect(fd_obj, image):

        rgb_src = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        result = fd_obj.detect_faces(rgb_src)

        if len(result) > 0:
            return result[0]['box']
        else:
            return None
```

Internally, this was basically how the pre-defined hyrbid MROI face detectors
(i.e., `MROI_HaarCascade` and `MROI_MTCNN`) was defined. Simply import them with

```python
from mroi_fd import MROI_HaarCascade, MROI_MTCNN
```

## Running the face detector

To use the face detector, simply instantiate the hybrid MROI face detector and
run it by invoking its `run` method. Below is a simple script that runs the
face detector and feed it images in a loop.

```python
fd = MROI_MTCNN()
fd.run() # This runs the face detector in the background.

cap = cv2.VideoCapture("/path/to/video/file")

while True:
	ret, frame = cap.read()

	# No more images; exit.
	if not ret:
		break

	# Feed the image into the face detector.
	fd.input_image(frame)

	# Get the ROI containing the face. This will be `None` if no face is
	# detected.
	ROI = fd.get_face_region()

	if ROI is not None:
		x, y, w, h = ROI
		cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

	cv2.imshow("MROI_MTCNN Face Detector", frame)

	if cv2.waitKey(1) == ord('q'):
		break

fd.clean()
cap.release()
cv2.destroyAllWindows()
```