Skip to content

Commit 7406da7

Browse files
committed
Rename object helper functions
1 parent 5961778 commit 7406da7

File tree

4 files changed

+112
-32
lines changed

4 files changed

+112
-32
lines changed

deepstack/core.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
## API urls
1313
URL_OBJECT_DETECTION = "http://{}:{}/v1/vision/detection"
1414
URL_FACE_DETECTION = "http://{}:{}/v1/vision/face"
15+
URL_FACE_REGISTRATION = "http://{}:{}/v1/vision/face/register"
16+
URL_FACE_RECOGNITION = "http://{}:{}/v1/vision/face/recognize"
1517

1618

1719
def format_confidence(confidence: Union[str, float]) -> float:
@@ -28,20 +30,20 @@ def get_confidences_above_threshold(
2830
return [val for val in confidences if val >= confidence_threshold]
2931

3032

31-
def get_object_labels(predictions: List[Dict]) -> List[str]:
33+
def get_objects(predictions: List[Dict]) -> List[str]:
3234
"""
33-
Get a list of the unique object labels predicted.
35+
Get a list of the unique objects predicted.
3436
"""
3537
labels = [pred["label"] for pred in predictions]
3638
return list(set(labels))
3739

3840

39-
def get_label_confidences(predictions: List[Dict], target_label: str):
41+
def get_object_confidences(predictions: List[Dict], target_object: str):
4042
"""
4143
Return the list of confidences of instances of target label.
4244
"""
4345
confidences = [
44-
pred["confidence"] for pred in predictions if pred["label"] == target_label
46+
pred["confidence"] for pred in predictions if pred["label"] == target_object
4547
]
4648
return confidences
4749

@@ -50,18 +52,19 @@ def get_objects_summary(predictions: List[Dict]):
5052
"""
5153
Get a summary of the objects detected.
5254
"""
53-
labels = get_object_labels(predictions)
55+
objects = get_objects(predictions)
5456
return {
55-
label: len(get_label_confidences(predictions, target_label=label))
56-
for label in labels
57+
target_object: len(get_object_confidences(predictions, target_object))
58+
for target_object in objects
5759
}
5860

5961

60-
def post_image(url: str, image: bytes, api_key: str, timeout: int):
62+
def post_image(url: str, image: bytes, api_key: str, timeout: int, data: dict = {}):
6163
"""Post an image to Deepstack."""
6264
try:
65+
data["api_key"] = api_key
6366
response = requests.post(
64-
url, files={"image": image}, data={"api_key": api_key}, timeout=timeout
67+
url, files={"image": image}, data=data, timeout=timeout
6568
)
6669
return response
6770
except requests.exceptions.Timeout:
@@ -99,7 +102,7 @@ def process_file(self, file_path: str):
99102
self.process_image_bytes(image_bytes)
100103

101104
def process_image_bytes(self, image_bytes: bytes):
102-
"""Process an image."""
105+
"""Process an image, performing detection."""
103106
self._predictions = []
104107
url = self._url_detection.format(self._ip_address, self._port)
105108

@@ -132,6 +135,7 @@ def __init__(
132135
ip_address, port, api_key, timeout, url_detection=URL_OBJECT_DETECTION
133136
)
134137

138+
135139
class DeepstackFace(Deepstack):
136140
"""Work with objects"""
137141

@@ -145,3 +149,23 @@ def __init__(
145149
super().__init__(
146150
ip_address, port, api_key, timeout, url_detection=URL_FACE_DETECTION
147151
)
152+
153+
def register_face(self, name: str, file_path: str):
154+
"""
155+
Register a face name to a file.
156+
"""
157+
158+
with open(file_path, "rb") as image:
159+
response = post_image(
160+
url=URL_FACE_REGISTRATION.format(self._ip_address, self._port),
161+
image=image,
162+
api_key=self._api_key,
163+
timeout=self._timeout,
164+
data={"userid": name},
165+
)
166+
167+
if response.status_code == 200 and response.json()["success"] == True:
168+
print("Taught face {} using file {}".format(name, file_path))
169+
elif response.status_code == 200 and response.json()["success"] == False:
170+
error = response.json()["error"]
171+
print("Error: {}".format(error))

tests/test_deepstack.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
MOCK_API_KEY = "mock_api_key"
1414
MOCK_TIMEOUT = 8
1515

16-
MOCK_RESPONSE = {
16+
MOCK_OBJECT_DETECTION_RESPONSE = {
1717
"success": True,
1818
"predictions": [
1919
{
@@ -43,19 +43,19 @@
4343
],
4444
}
4545

46-
MOCK_PREDICTIONS = MOCK_RESPONSE["predictions"]
47-
MOCK_CONFIDENCES = [0.6998661, 0.7996547]
46+
MOCK_OBJECT_PREDICTIONS = MOCK_OBJECT_DETECTION_RESPONSE["predictions"]
47+
MOCK_OBJECT_CONFIDENCES = [0.6998661, 0.7996547]
4848
CONFIDENCE_THRESHOLD = 0.7
4949

5050

5151
def test_DeepstackObject_process_image_bytes():
5252
"""Test a good response from server."""
5353
with requests_mock.Mocker() as mock_req:
54-
mock_req.post(MOCK_URL, status_code=ds.HTTP_OK, json=MOCK_RESPONSE)
54+
mock_req.post(MOCK_URL, status_code=ds.HTTP_OK, json=MOCK_OBJECT_DETECTION_RESPONSE)
5555

5656
dsobject = ds.DeepstackObject(MOCK_IP_ADDRESS, MOCK_PORT)
5757
dsobject.process_image_bytes(MOCK_BYTES)
58-
assert dsobject.predictions == MOCK_PREDICTIONS
58+
assert dsobject.predictions == MOCK_OBJECT_PREDICTIONS
5959

6060

6161
def test_DeepstackObject_process_image_bytes_timeout():
@@ -69,27 +69,27 @@ def test_DeepstackObject_process_image_bytes_timeout():
6969
assert "SHOULD FAIL" in str(excinfo.value)
7070

7171

72-
def test_get_object_labels():
72+
def test_get_objects():
7373
"""Cant always be sure order of returned list items."""
74-
object_labels = ds.get_object_labels(MOCK_PREDICTIONS)
75-
assert type(object_labels) is list
76-
assert "dog" in object_labels
77-
assert "person" in object_labels
78-
assert len(object_labels) == 2
74+
objects = ds.get_objects(MOCK_OBJECT_PREDICTIONS)
75+
assert type(objects) is list
76+
assert "dog" in objects
77+
assert "person" in objects
78+
assert len(objects) == 2
7979

8080

8181
def test_get_objects_summary():
82-
objects_summary = ds.get_objects_summary(MOCK_PREDICTIONS)
82+
objects_summary = ds.get_objects_summary(MOCK_OBJECT_PREDICTIONS)
8383
assert objects_summary == {"dog": 1, "person": 2}
8484

8585

86-
def test_get_label_confidences():
87-
label_confidences = ds.get_label_confidences(MOCK_PREDICTIONS, "person")
88-
assert label_confidences == MOCK_CONFIDENCES
86+
def test_get_object_confidences():
87+
object_confidences = ds.get_object_confidences(MOCK_OBJECT_PREDICTIONS, "person")
88+
assert object_confidences == MOCK_OBJECT_CONFIDENCES
8989

9090

9191
def test_get_confidences_above_threshold():
9292
assert (
93-
len(ds.get_confidences_above_threshold(MOCK_CONFIDENCES, CONFIDENCE_THRESHOLD))
93+
len(ds.get_confidences_above_threshold(MOCK_OBJECT_CONFIDENCES, CONFIDENCE_THRESHOLD))
9494
== 1
9595
)

usage-face-recognition.ipynb

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
},
9090
{
9191
"cell_type": "code",
92-
"execution_count": 7,
92+
"execution_count": 5,
9393
"metadata": {},
9494
"outputs": [
9595
{
@@ -118,7 +118,7 @@
118118
},
119119
{
120120
"cell_type": "code",
121-
"execution_count": 8,
121+
"execution_count": 6,
122122
"metadata": {},
123123
"outputs": [
124124
{
@@ -136,7 +136,7 @@
136136
" 'x_max': 1199}]"
137137
]
138138
},
139-
"execution_count": 8,
139+
"execution_count": 6,
140140
"metadata": {},
141141
"output_type": "execute_result"
142142
}
@@ -147,7 +147,7 @@
147147
},
148148
{
149149
"cell_type": "code",
150-
"execution_count": 11,
150+
"execution_count": 7,
151151
"metadata": {},
152152
"outputs": [
153153
{
@@ -156,7 +156,7 @@
156156
"2"
157157
]
158158
},
159-
"execution_count": 11,
159+
"execution_count": 7,
160160
"metadata": {},
161161
"output_type": "execute_result"
162162
}
@@ -165,6 +165,52 @@
165165
"len(dsface.predictions)"
166166
]
167167
},
168+
{
169+
"cell_type": "markdown",
170+
"metadata": {},
171+
"source": [
172+
"## Register a face"
173+
]
174+
},
175+
{
176+
"cell_type": "code",
177+
"execution_count": 8,
178+
"metadata": {},
179+
"outputs": [
180+
{
181+
"name": "stdout",
182+
"output_type": "stream",
183+
"text": [
184+
"Taught face idris using file tests/images/couple.jpg\n"
185+
]
186+
}
187+
],
188+
"source": [
189+
"dsface.register_face(name=\"idris\", file_path = 'tests/images/couple.jpg')"
190+
]
191+
},
192+
{
193+
"cell_type": "code",
194+
"execution_count": 10,
195+
"metadata": {},
196+
"outputs": [
197+
{
198+
"ename": "FileNotFoundError",
199+
"evalue": "[Errno 2] No such file or directory: 'tests/images/couplesdf.jpg'",
200+
"output_type": "error",
201+
"traceback": [
202+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
203+
"\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)",
204+
"\u001b[0;32m<ipython-input-10-ab14dae0eb4a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdsface\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregister_face\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"idris\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfile_path\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'tests/images/couplesdf.jpg'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
205+
"\u001b[0;32m~/Github/deepstack-python/deepstack/core.py\u001b[0m in \u001b[0;36mregister_face\u001b[0;34m(self, name, file_path)\u001b[0m\n\u001b[1;32m 155\u001b[0m \"\"\"\n\u001b[1;32m 156\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 157\u001b[0;31m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfile_path\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"rb\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mimage\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 158\u001b[0m response = post_image(\n\u001b[1;32m 159\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mURL_FACE_REGISTRATION\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_ip_address\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_port\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
206+
"\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'tests/images/couplesdf.jpg'"
207+
]
208+
}
209+
],
210+
"source": [
211+
"dsface.register_face(name=\"idris\", file_path = 'tests/images/couplesdf.jpg')"
212+
]
213+
},
168214
{
169215
"cell_type": "markdown",
170216
"metadata": {},
@@ -173,6 +219,17 @@
173219
"The package provides helper functions for extracting info out of deepstack predictions"
174220
]
175221
},
222+
{
223+
"cell_type": "code",
224+
"execution_count": null,
225+
"metadata": {},
226+
"outputs": [],
227+
"source": [
228+
"name=\"idris\"\n",
229+
"file_path=\"foo.jpg\"\n",
230+
"print(\"Taught face {} using file {}\".format(name, file_path))"
231+
]
232+
},
176233
{
177234
"cell_type": "code",
178235
"execution_count": null,

usage-object-detection.ipynb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@
106106
"#%%time\n",
107107
"try:\n",
108108
" dsobject.process_file(image_path)\n",
109-
" print(dsobject.predictions)\n",
110109
"except ds.DeepstackException as exc:\n",
111110
" print(exc)"
112111
]

0 commit comments

Comments
 (0)