Skip to content

Commit

Permalink
Add gender age model
Browse files Browse the repository at this point in the history
  • Loading branch information
jrrodri committed Dec 7, 2024
1 parent 73b5996 commit ba9284a
Show file tree
Hide file tree
Showing 23 changed files with 86 additions and 28 deletions.
48 changes: 32 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ show_image(img)

## Remove unwanted objects

Directly remove unwanted objects in images and photos locally.
Directly remove unwanted objects in images and photos locally. Just click on the object and press the "spacebar" to automatically select and delete the object from the image. Finally, press "s" to save the final image.

```python
from abraia.utils import load_image, Sketcher
Expand All @@ -161,6 +161,29 @@ sketcher.run(lama.predict)

![inpaint output](https://github.com/abraia/abraia-multiple/raw/master/images/inpaint-output.jpg)

## Gender Age model

Model to predict gender and age. It can be useful to anonymize minors faces.

```python
from abraia.faces import Recognition, Attribute
from abraia.utils import load_image, show_image
from abraia.draw import render_results

recognition = Recognition()
attribute = Attribute()

img = load_image('images/image.jpg')
results = recognition.detect_faces(img)
faces = recognition.extract_faces(img, results)
for face, result in zip(faces, results):
gender, age, score = attribute.predict(face)
result['label'] = f"{gender} {age}"
result['confidence'] = score
img = render_results(img, results)
show_image(img)
```

## Command line interface

The Abraia CLI provides access to the Abraia Cloud Platform through the command line. It makes simple to manage your files and enables bulk image editing capabilities. It provides and easy way to resize, convert, and compress your images - JPEG, WebP, or PNG -, and get them ready to publish on the web. Moreover, you can automatically remove the background, upscale, or anonymize your images in bulk.
Expand All @@ -173,7 +196,7 @@ Automatically remove images background and make them transparent in bulk.
abraia editing removebg "*.jpg"
```

![bolt transparent background](https://github.com/abraia/abraia-multiple/raw/master/images/usain-bolt.png)
![removebg output](https://github.com/abraia/abraia-multiple/raw/master/images/removebg-output.png)

### Upscale images

Expand Down Expand Up @@ -203,25 +226,18 @@ Compress images in bulk specifying the input glob pattern or folder:
abraia editing convert "images/bird*.jpg"
```

![Image compressed from url](https://github.com/abraia/abraia-multiple/raw/master/images/birds_o.jpg)

Resize and optimize images maintaining the aspect ratio just specifying the `width` or the `height` of the new image:

```sh
abraia editing convert images/usain-bolt.jpeg --width 500
```

![Usain Bolt resized](https://github.com/abraia/abraia-multiple/raw/master/images/usain-bolt_500.jpeg)
![image optimized](https://github.com/abraia/abraia-multiple/raw/master/images/birds_optimized.jpg)

You can also automatically change the aspect ratio specifying both `width` and `height` parameters and setting the resize `mode` (pad, crop, thumb):
Automatically change the aspect ratio specifying both `width` and `height` parameters and setting the resize `mode` (pad, crop, thumb). Or simply resize images maintaining the aspect ratio just specifying the `width` or the `height` of the new image:

```sh
abraia editing convert images/lion.jpg --width 333 --height 333 --mode pad
abraia editing convert images/lion.jpg --width 333 --height 333
abraia editing convert images/birds.jpg --width 375 --height 375 --mode pad
abraia editing convert images/birds.jpg --width 375 --height 375
abraia editing convert images/birds.jpg --width 750
```

![Image lion smart cropped](https://github.com/abraia/abraia-multiple/raw/master/images/lion_333x333_pad.jpg)
![Image lion smart cropped](https://github.com/abraia/abraia-multiple/raw/master/images/lion_333x333.jpg)
![image padded](https://github.com/abraia/abraia-multiple/raw/master/images/birds_padded.jpg)
![image smart cropped](https://github.com/abraia/abraia-multiple/raw/master/images/birds_cropped.jpg)

So, you can automatically resize all the images in a specific folder preserving the aspect ration of each image just specifying the target `width` or `height`:

Expand Down
7 changes: 1 addition & 6 deletions abraia/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
import onnxruntime as ort

from .ops import py_cpu_nms, normalize, mask_to_polygon
from .ops import py_cpu_nms, normalize, mask_to_polygon, softmax
from .utils import download_file, load_json, get_color, get_providers
from .utils import load_image, show_image, save_image, Video
from .draw import render_results
Expand All @@ -30,11 +30,6 @@ def preprocess(img):
return np.expand_dims(img.transpose((2, 0, 1)), axis=0)


def softmax(x):
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum(axis=0)


def postprocess(outputs, classes):
probs = softmax(outputs[0].flatten())
idx = np.argmax(probs)
Expand Down
14 changes: 9 additions & 5 deletions abraia/faces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .retinaface import Retinaface
from .arcface import ArcFace
from .transform import align_face
from .genderage import Attribute


def euclidean_distance(feat1, feat2):
Expand Down Expand Up @@ -35,11 +36,14 @@ def represent_faces(self, img, results=None, size=112):

def identify_faces(self, results, index, threshold=0.45):
for result in results:
sims = [cosine_similarity(result['embeddings'], ind['embeddings']) for ind in index]
idx = np.argmax(sims)
if sims[idx] > threshold:
result['confidence'] = sims[idx]
result['label'] = index[idx]['name']
del result['confidence']
result['label'] = 'unknow'
if len(index):
sims = [cosine_similarity(result['embeddings'], ind['embeddings']) for ind in index]
idx = np.argmax(sims)
if sims[idx] > threshold:
result['confidence'] = sims[idx]
result['label'] = index[idx]['name']
return results


Expand Down
38 changes: 38 additions & 0 deletions abraia/faces/genderage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import cv2
import numpy as np
import onnxruntime as ort

from ..utils import download_file
from ..ops import softmax


class Attribute:
def __init__(self):
"""Age and Gender Prediction"""
self.input_std = 1.0
self.input_mean = 0.0

model_src = download_file('multiple/models/faces/genderage.simplified.onnx')
self.session = ort.InferenceSession(model_src, None)

inputs = self.session.get_inputs()
self.input_size = tuple(inputs[0].shape[2:][::-1])

self.input_names = [x.name for x in self.session.get_inputs()]
self.output_names = [x.name for x in self.session.get_outputs()]

def preprocess(self, transformed_image):
return cv2.dnn.blobFromImage(transformed_image, 1.0 / self.input_std,
self.input_size, (self.input_mean, self.input_mean, self.input_mean), swapRB=True)

def postprocess(self, predictions):
scores = softmax(predictions[:2])
gender = int(np.argmax(scores))
age = int(np.round(predictions[2]*100))
return 'Male' if gender == 1 else 'Female', age, float(scores[gender])

def predict(self, face):
blob = self.preprocess(face)
predictions = self.session.run(self.output_names, {self.input_names[0]: blob})[0][0]
gender, age, score = self.postprocess(predictions)
return gender, age, score
5 changes: 5 additions & 0 deletions abraia/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,8 @@ def non_maximum_suppression(objects, iou_threshold):
idxs = py_cpu_nms(np.array(dets), iou_threshold)
return [objects[idx] for idx in idxs]
return []


def softmax(x):
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum(axis=0)
2 changes: 1 addition & 1 deletion abraia/utils/sketcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def draw_mask(img, mask, color, opacity = 1):


class Sketcher:
def __init__(self, img, radius=15):
def __init__(self, img, radius=11):
print(__doc__)
self.prev_pt = None
self.win_name = 'Image'
Expand Down
File renamed without changes
File renamed without changes
Binary file added images/birds_padded.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
Binary file removed images/bolt.png
Binary file not shown.
Binary file removed images/branded.jpg
Binary file not shown.
Binary file added images/image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/lion_333x333.jpg
Binary file not shown.
Binary file removed images/lion_333x333_pad.jpg
Binary file not shown.
Binary file removed images/lion_500.jpg
Binary file not shown.
Binary file removed images/lion_o.jpg
Binary file not shown.
Binary file added images/mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/removebg-output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/stock_gs200.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed images/usain-bolt.png
Binary file not shown.
Binary file removed images/usain-bolt_500.jpeg
Binary file not shown.
Binary file removed images/usain-bolt_500x500.jpeg
Binary file not shown.

0 comments on commit ba9284a

Please sign in to comment.