зеркало из
https://github.com/ssciwr/AMMICO.git
synced 2025-10-29 13:06:04 +02:00
Add DeepFace exploration notebook and Python package
Этот коммит содержится в:
родитель
b28e8ab5fe
Коммит
2d3ea26007
@ -5,11 +5,11 @@ repos:
|
||||
- id: nbstripout
|
||||
files: ".ipynb"
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 21.11b0
|
||||
rev: 22.6.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/dfm/black_nbconvert
|
||||
rev: v0.3.0
|
||||
rev: v0.4.0
|
||||
hooks:
|
||||
- id: black_nbconvert
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
|
||||
28
Dockerfile
Обычный файл
28
Dockerfile
Обычный файл
@ -0,0 +1,28 @@
|
||||
FROM jupyter/base-notebook:2022-06-06
|
||||
|
||||
# Install system dependencies for computer vision packages
|
||||
USER root
|
||||
RUN apt update && apt install -y libgl1 libglib2.0-0 libsm6 libxrender1 libxext6
|
||||
USER $NB_USER
|
||||
|
||||
# Copy the repository into the container
|
||||
COPY --chown=${NB_UID} . /opt/misinformation
|
||||
|
||||
# Install the Python package
|
||||
RUN python -m pip install /opt/misinformation
|
||||
|
||||
# Make JupyterLab the default for this application
|
||||
ENV JUPYTER_ENABLE_LAB=yes
|
||||
|
||||
# Export where the data is located
|
||||
ENV XDG_DATA_HOME=/opt/misinformation/data
|
||||
|
||||
# Copy notebooks into the home directory
|
||||
RUN rm -rf $HOME/work
|
||||
RUN cp /opt/misinformation/notebooks/*.ipynb $HOME
|
||||
|
||||
# Execute the facial recognition notebook once in order to bundle
|
||||
# the pre-built models (that are downloaded on demand) into the
|
||||
# Docker image.
|
||||
RUN python -m pip install nbclick && \
|
||||
python -m nbclick /opt/misinformation/notebooks/facial_expressions.ipynb
|
||||
0
data/.keep
Обычный файл
0
data/.keep
Обычный файл
8
misinformation/__init__.py
Обычный файл
8
misinformation/__init__.py
Обычный файл
@ -0,0 +1,8 @@
|
||||
from importlib import metadata
|
||||
|
||||
|
||||
# Export the version defined in project metadata
|
||||
__version__ = metadata.version(__package__)
|
||||
del metadata
|
||||
|
||||
from misinformation.faces import explore_face_recognition, find_files
|
||||
89
misinformation/faces.py
Обычный файл
89
misinformation/faces.py
Обычный файл
@ -0,0 +1,89 @@
|
||||
import glob
|
||||
import ipywidgets
|
||||
import os
|
||||
|
||||
from IPython.display import display
|
||||
from deepface import DeepFace
|
||||
|
||||
|
||||
def find_files(path=None, pattern="*.png", recursive=True, limit=20):
|
||||
"""Find image files on the file system
|
||||
|
||||
:param path:
|
||||
The base directory where we are looking for the images. Defaults
|
||||
to None, which uses the XDG data directory if set or the current
|
||||
working directory otherwise.
|
||||
:param pattern:
|
||||
The naming pattern that the filename should match. Defaults to
|
||||
"*.png". Can be used to allow other patterns or to only include
|
||||
specific prefixes or suffixes.
|
||||
:param recursive:
|
||||
Whether to recurse into subdirectories.
|
||||
:param limit:
|
||||
The maximum number of images to be found. Defaults to 20.
|
||||
To return all images, set to None.
|
||||
"""
|
||||
if path is None:
|
||||
path = os.environ.get("XDG_DATA_HOME", ".")
|
||||
|
||||
result = list(glob.glob(f"{path}/{pattern}", recursive=recursive))
|
||||
|
||||
if limit is not None:
|
||||
result = result[:limit]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def facial_expression_analysis(img_path):
|
||||
return DeepFace.analyze(
|
||||
img_path=img_path, actions=["age", "gender", "race", "emotion"], prog_bar=False
|
||||
)
|
||||
|
||||
|
||||
class JSONContainer:
|
||||
"""Expose a Python dictionary as a JSON document in JupyterLab
|
||||
rich display rendering.
|
||||
"""
|
||||
|
||||
def __init__(self, data={}):
|
||||
self._data = data
|
||||
|
||||
def _repr_json_(self):
|
||||
return self._data
|
||||
|
||||
|
||||
def explore_face_recognition(image_paths):
|
||||
# Set up the facial recognition output widget
|
||||
output = ipywidgets.Output(layout=ipywidgets.Layout(width="30%"))
|
||||
|
||||
# Set up the image selection and display widget
|
||||
images = [ipywidgets.Image.from_file(p) for p in image_paths]
|
||||
image_widget = ipywidgets.Tab(
|
||||
children=images,
|
||||
titles=[f"#{i}" for i in range(len(image_paths))],
|
||||
layout=ipywidgets.Layout(width="70%"),
|
||||
)
|
||||
|
||||
# Register the facial recognition logic
|
||||
def _recognition(_):
|
||||
data = {}
|
||||
data["filename"] = image_paths[image_widget.selected_index]
|
||||
|
||||
try:
|
||||
data["deepface_results"] = facial_expression_analysis(data["filename"])
|
||||
data["deepface_find_face"] = True
|
||||
except ValueError:
|
||||
data["deepface_find_face"] = False
|
||||
|
||||
output.clear_output()
|
||||
with output:
|
||||
display(JSONContainer(data))
|
||||
|
||||
# Register the handler and trigger it immediately
|
||||
image_widget.observe(_recognition, names=("selected_index",), type="change")
|
||||
|
||||
with ipywidgets.Output():
|
||||
_recognition(None)
|
||||
|
||||
# Show the combined widget
|
||||
return ipywidgets.HBox([image_widget, output])
|
||||
105
notebooks/facial_expressions.ipynb
Обычный файл
105
notebooks/facial_expressions.ipynb
Обычный файл
@ -0,0 +1,105 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d2c4d40d-8aca-4024-8d19-a65c4efe825d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Facial Expression recognition with DeepFace"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "51f8888b-d1a3-4b85-a596-95c0993fa192",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"This notebooks shows some preliminary work on detecting facial expressions with DeepFace. It is mainly meant to explore its capabilities and to decide on future research directions. We package our code into a `misinformation` package that is imported here:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b21e52a5-d379-42db-aae6-f2ab9ed9a369",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import misinformation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "949d9f00-b129-477a-bc1d-e68fed73af2d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We select a subset of image files to try facial expression detection on. The `find_files` function finds image files within a given directory:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "afe7e638-f09d-47e7-9295-1c374bd64c53",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"images = misinformation.find_files()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e149bfe5-90b0-49b2-af3d-688e41aab019",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If you want to fine tune the discovery of image files, you can provide more parameters:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f38bb8ed-1004-4e33-8ed6-793cb5869400",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"?misinformation.find_files"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d8067ad1-ef8a-4e91-bcc6-f8dbef771854",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Next, we display the face recognition results provided by the DeepFace library. Click on the tabs to see the results in the right sidebar:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "992499ed-33f1-4425-ad5d-738cf565d175",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"misinformation.explore_face_recognition(images)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
29
pyproject.toml
Обычный файл
29
pyproject.toml
Обычный файл
@ -0,0 +1,29 @@
|
||||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=61",
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "misinformation"
|
||||
version = "0.0.1"
|
||||
description = "Misinformation campaign analysis"
|
||||
readme = "README.md"
|
||||
maintainers = [
|
||||
{ name = "Inga Ulusoy", email = "ssc@iwr.uni-heidelberg.de" },
|
||||
{ name = "Dominic Kempf", email = "ssc@iwr.uni-heidelberg.de" },
|
||||
]
|
||||
requires-python = ">=3.8"
|
||||
license = { text = "MIT" }
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3",
|
||||
"Operating System :: OS Independent",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
]
|
||||
dependencies = [
|
||||
"deepface",
|
||||
"ipywidgets ==8.0.0rc1",
|
||||
]
|
||||
|
||||
[tool.setuptools]
|
||||
packages = ["misinformation"]
|
||||
4
setup.py
Обычный файл
4
setup.py
Обычный файл
@ -0,0 +1,4 @@
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
setup()
|
||||
Загрузка…
x
Ссылка в новой задаче
Block a user