person-identification 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- person_identification-0.1.0/LICENSE +21 -0
- person_identification-0.1.0/PKG-INFO +12 -0
- person_identification-0.1.0/README.md +171 -0
- person_identification-0.1.0/pyproject.toml +20 -0
- person_identification-0.1.0/setup.cfg +4 -0
- person_identification-0.1.0/src/person_identification/__init__.py +3 -0
- person_identification-0.1.0/src/person_identification/archFace_engine.py +60 -0
- person_identification-0.1.0/src/person_identification/config.py +84 -0
- person_identification-0.1.0/src/person_identification/create_database.py +426 -0
- person_identification-0.1.0/src/person_identification/face_detector.py +110 -0
- person_identification-0.1.0/src/person_identification/main.py +902 -0
- person_identification-0.1.0/src/person_identification/search.py +353 -0
- person_identification-0.1.0/src/person_identification/setup_sample_data.py +32 -0
- person_identification-0.1.0/src/person_identification/utils.py +0 -0
- person_identification-0.1.0/src/person_identification/yolo_detection.py +33 -0
- person_identification-0.1.0/src/person_identification.egg-info/PKG-INFO +12 -0
- person_identification-0.1.0/src/person_identification.egg-info/SOURCES.txt +18 -0
- person_identification-0.1.0/src/person_identification.egg-info/dependency_links.txt +1 -0
- person_identification-0.1.0/src/person_identification.egg-info/requires.txt +5 -0
- person_identification-0.1.0/src/person_identification.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Monu Maurya
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: person-identification
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Face identification and image search package
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Dist: numpy
|
|
8
|
+
Requires-Dist: opencv-python
|
|
9
|
+
Requires-Dist: faiss-cpu
|
|
10
|
+
Requires-Dist: insightface
|
|
11
|
+
Requires-Dist: onnxruntime
|
|
12
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Person Identification
|
|
2
|
+
|
|
3
|
+
`person-identification` is a Python package for **face detection, face recognition, and image search**.
|
|
4
|
+
|
|
5
|
+
The package can detect faces from images, generate face embeddings using ArcFace, and search for similar faces using a vector similarity index such as FAISS.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
* Face detection from images
|
|
10
|
+
* Face embedding generation using ArcFace
|
|
11
|
+
* Similar face search
|
|
12
|
+
* FAISS-based vector similarity search
|
|
13
|
+
* Configurable similarity threshold
|
|
14
|
+
* Top-K similar image retrieval
|
|
15
|
+
* Python package with a public API
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### From source
|
|
20
|
+
|
|
21
|
+
Clone or download the project and navigate to the project directory:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd app
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Install the package:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For development and testing:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install -e ".[test]"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Requirements
|
|
40
|
+
|
|
41
|
+
* Python 3.10+
|
|
42
|
+
* NumPy
|
|
43
|
+
* OpenCV
|
|
44
|
+
* FAISS
|
|
45
|
+
* InsightFace
|
|
46
|
+
* ONNX Runtime
|
|
47
|
+
|
|
48
|
+
The required dependencies are defined in `pyproject.toml`.
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
Import the public API:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from person_identification import FaceSearch
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Create a `FaceSearch` instance:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
search = FaceSearch()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
You can then use the search functionality provided by the package.
|
|
65
|
+
|
|
66
|
+
## Example
|
|
67
|
+
|
|
68
|
+
Example usage:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from person_identification import FaceSearch
|
|
72
|
+
|
|
73
|
+
search = FaceSearch()
|
|
74
|
+
|
|
75
|
+
results = search.search("path/to/query/image.jpg")
|
|
76
|
+
|
|
77
|
+
print(results)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The search process is conceptually:
|
|
81
|
+
|
|
82
|
+
Query Image
|
|
83
|
+
↓
|
|
84
|
+
Face Detection
|
|
85
|
+
↓
|
|
86
|
+
ArcFace Embedding
|
|
87
|
+
↓
|
|
88
|
+
FAISS Similarity Search
|
|
89
|
+
↓
|
|
90
|
+
Similar Images
|
|
91
|
+
|
|
92
|
+
````
|
|
93
|
+
|
|
94
|
+
## API Usage
|
|
95
|
+
|
|
96
|
+
### `FaceSearch`
|
|
97
|
+
|
|
98
|
+
`FaceSearch` is the main public interface of the package.
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from person_identification import FaceSearch
|
|
102
|
+
|
|
103
|
+
search = FaceSearch()
|
|
104
|
+
````
|
|
105
|
+
|
|
106
|
+
The class internally handles the face-search pipeline, including face detection, embedding generation, and similarity search.
|
|
107
|
+
|
|
108
|
+
### Search
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
results = search.search("query.jpg")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The search method accepts a query image and returns matching or similar images based on face similarity.
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
The package supports configurable parameters such as:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
TOP_K = 10
|
|
122
|
+
SIMILARITY_THRESHOLD = 0.45
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
* `TOP_K` — number of similar results to retrieve.
|
|
126
|
+
* `SIMILARITY_THRESHOLD` — minimum similarity required for a match.
|
|
127
|
+
|
|
128
|
+
Configuration values can be adjusted according to the dataset and use case.
|
|
129
|
+
|
|
130
|
+
## Testing
|
|
131
|
+
|
|
132
|
+
The package uses `pytest`.
|
|
133
|
+
|
|
134
|
+
Run all tests:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pytest
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Run a specific test:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pytest tests/test_search.py
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Limitations
|
|
147
|
+
|
|
148
|
+
* Face recognition accuracy depends on image quality.
|
|
149
|
+
* Very blurry or low-resolution images may produce poor results.
|
|
150
|
+
* Different lighting, pose, occlusion, and facial expressions can affect similarity.
|
|
151
|
+
* Large datasets require appropriate vector indexing and memory resources.
|
|
152
|
+
* ArcFace/InsightFace models can require significant CPU, RAM, and storage resources.
|
|
153
|
+
* FAISS index and image mapping must remain synchronized.
|
|
154
|
+
* The package is currently designed primarily for image-based face search.
|
|
155
|
+
|
|
156
|
+
## Project Status
|
|
157
|
+
|
|
158
|
+
This package is currently under development.
|
|
159
|
+
|
|
160
|
+
Future improvements may include:
|
|
161
|
+
|
|
162
|
+
* Better large-scale indexing
|
|
163
|
+
* GPU acceleration
|
|
164
|
+
* Improved face detection
|
|
165
|
+
* Batch processing
|
|
166
|
+
* More configurable search options
|
|
167
|
+
* Additional vector database support
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
This project is currently intended for internal/development use.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "person-identification"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Face identification and image search package"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
"numpy",
|
|
13
|
+
"opencv-python",
|
|
14
|
+
"faiss-cpu",
|
|
15
|
+
"insightface",
|
|
16
|
+
"onnxruntime",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[tool.setuptools.packages.find]
|
|
20
|
+
where = ["src"]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from insightface.app import FaceAnalysis
|
|
3
|
+
from .config import ARCFACE_MODEL_NAME
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ArchFaceEngine:
|
|
7
|
+
|
|
8
|
+
def __init__(self):
|
|
9
|
+
# insightface model load
|
|
10
|
+
self.app = FaceAnalysis(
|
|
11
|
+
name=ARCFACE_MODEL_NAME,
|
|
12
|
+
providers=[
|
|
13
|
+
"CPUExecutionProvider"
|
|
14
|
+
]
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# model initialize
|
|
18
|
+
self.app.prepare(
|
|
19
|
+
ctx_id=0,
|
|
20
|
+
det_size=(640, 640)
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
def get_embedding(self, image):
|
|
24
|
+
faces = self.app.get(image)
|
|
25
|
+
if len(faces) == 0:
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
embedding = self.normalize(
|
|
29
|
+
faces[0].normed_embedding
|
|
30
|
+
)
|
|
31
|
+
return embedding
|
|
32
|
+
|
|
33
|
+
def get_embedding_from_face(self, face):
|
|
34
|
+
"""
|
|
35
|
+
Use the normed_embedding already computed
|
|
36
|
+
by the detection model on a detected face.
|
|
37
|
+
This avoids re-detecting on a small crop,
|
|
38
|
+
which often returns no faces.
|
|
39
|
+
"""
|
|
40
|
+
if face is None:
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
embedding = face.normed_embedding
|
|
44
|
+
|
|
45
|
+
if embedding is None:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
return self.normalize(embedding)
|
|
49
|
+
|
|
50
|
+
def normalize(self, embedding):
|
|
51
|
+
embedding = np.array(
|
|
52
|
+
embedding,
|
|
53
|
+
)
|
|
54
|
+
norm = np.linalg.norm(
|
|
55
|
+
embedding
|
|
56
|
+
)
|
|
57
|
+
if norm == 0:
|
|
58
|
+
return embedding
|
|
59
|
+
|
|
60
|
+
return embedding / norm
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
#base directory
|
|
4
|
+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
5
|
+
|
|
6
|
+
#API config
|
|
7
|
+
API_URL = "http://gms.axeplay.in/api/get-accreditation-data"
|
|
8
|
+
|
|
9
|
+
ALL_IMAGES_PATH = os.path.join(
|
|
10
|
+
BASE_DIR,
|
|
11
|
+
"dataset",
|
|
12
|
+
"Picflow Images Aug 13"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
QUERY_IMAGES_PATH = os.path.join(
|
|
16
|
+
BASE_DIR,
|
|
17
|
+
"dataset",
|
|
18
|
+
"query_images"
|
|
19
|
+
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
#model paths
|
|
23
|
+
YOLO_MODEL_PATH = os.path.join(
|
|
24
|
+
BASE_DIR,
|
|
25
|
+
"models",
|
|
26
|
+
"yolo",
|
|
27
|
+
"yolov5s.pt"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
#archface
|
|
31
|
+
ARCFACE_MODEL_NAME = "buffalo_l"
|
|
32
|
+
|
|
33
|
+
EMBEDDING_DIR = os.path.join(
|
|
34
|
+
BASE_DIR,
|
|
35
|
+
"embedding"
|
|
36
|
+
)
|
|
37
|
+
FAISS_INDEX_PATH = os.path.join(
|
|
38
|
+
EMBEDDING_DIR,
|
|
39
|
+
"faiss_index.faiss"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
IMAGE_MAPPING_PATH = os.path.join(
|
|
43
|
+
EMBEDDING_DIR,
|
|
44
|
+
"image_mapping.pkl"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
TOP_K = 10
|
|
48
|
+
SIMILARITY_THRESHOLD = 0.45
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
IMAGE_SIZE = (112, 112)
|
|
52
|
+
FACE_size = (112, 112)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
SUPPORTED_EXTENSIONS = [
|
|
56
|
+
".JPG",
|
|
57
|
+
".JPEG",
|
|
58
|
+
".PNG",
|
|
59
|
+
".GIF",
|
|
60
|
+
".BMP",
|
|
61
|
+
".TIFF",
|
|
62
|
+
".WEBP",
|
|
63
|
+
".jpg",
|
|
64
|
+
".jpeg",
|
|
65
|
+
".png",
|
|
66
|
+
".gif",
|
|
67
|
+
".bmp",
|
|
68
|
+
".tiff",
|
|
69
|
+
".webp"
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
#performance
|
|
74
|
+
BATCH_SIZE = 32
|
|
75
|
+
NUM_WORKERS = 4
|
|
76
|
+
|
|
77
|
+
OUTPUT_DIR = os.path.join(
|
|
78
|
+
BASE_DIR,
|
|
79
|
+
"output"
|
|
80
|
+
)
|
|
81
|
+
MATCHED_IMAGES_DIR = os.path.join(
|
|
82
|
+
OUTPUT_DIR,
|
|
83
|
+
"matched_images"
|
|
84
|
+
)
|