From 7406da7c41d55f62440f140a1a8035937c643b6e Mon Sep 17 00:00:00 2001 From: Robin Cole Date: Sat, 14 Sep 2019 09:13:50 +0100 Subject: [PATCH 1/5] Rename object helper functions --- deepstack/core.py | 44 +++++++++++++++++------ tests/test_deepstack.py | 32 ++++++++--------- usage-face-recognition.ipynb | 67 +++++++++++++++++++++++++++++++++--- usage-object-detection.ipynb | 1 - 4 files changed, 112 insertions(+), 32 deletions(-) diff --git a/deepstack/core.py b/deepstack/core.py index 66277d6..10cf2ed 100644 --- a/deepstack/core.py +++ b/deepstack/core.py @@ -12,6 +12,8 @@ ## API urls URL_OBJECT_DETECTION = "http://{}:{}/v1/vision/detection" URL_FACE_DETECTION = "http://{}:{}/v1/vision/face" +URL_FACE_REGISTRATION = "http://{}:{}/v1/vision/face/register" +URL_FACE_RECOGNITION = "http://{}:{}/v1/vision/face/recognize" def format_confidence(confidence: Union[str, float]) -> float: @@ -28,20 +30,20 @@ def get_confidences_above_threshold( return [val for val in confidences if val >= confidence_threshold] -def get_object_labels(predictions: List[Dict]) -> List[str]: +def get_objects(predictions: List[Dict]) -> List[str]: """ - Get a list of the unique object labels predicted. + Get a list of the unique objects predicted. """ labels = [pred["label"] for pred in predictions] return list(set(labels)) -def get_label_confidences(predictions: List[Dict], target_label: str): +def get_object_confidences(predictions: List[Dict], target_object: str): """ Return the list of confidences of instances of target label. """ confidences = [ - pred["confidence"] for pred in predictions if pred["label"] == target_label + pred["confidence"] for pred in predictions if pred["label"] == target_object ] return confidences @@ -50,18 +52,19 @@ def get_objects_summary(predictions: List[Dict]): """ Get a summary of the objects detected. """ - labels = get_object_labels(predictions) + objects = get_objects(predictions) return { - label: len(get_label_confidences(predictions, target_label=label)) - for label in labels + target_object: len(get_object_confidences(predictions, target_object)) + for target_object in objects } -def post_image(url: str, image: bytes, api_key: str, timeout: int): +def post_image(url: str, image: bytes, api_key: str, timeout: int, data: dict = {}): """Post an image to Deepstack.""" try: + data["api_key"] = api_key response = requests.post( - url, files={"image": image}, data={"api_key": api_key}, timeout=timeout + url, files={"image": image}, data=data, timeout=timeout ) return response except requests.exceptions.Timeout: @@ -99,7 +102,7 @@ def process_file(self, file_path: str): self.process_image_bytes(image_bytes) def process_image_bytes(self, image_bytes: bytes): - """Process an image.""" + """Process an image, performing detection.""" self._predictions = [] url = self._url_detection.format(self._ip_address, self._port) @@ -132,6 +135,7 @@ def __init__( ip_address, port, api_key, timeout, url_detection=URL_OBJECT_DETECTION ) + class DeepstackFace(Deepstack): """Work with objects""" @@ -145,3 +149,23 @@ def __init__( super().__init__( ip_address, port, api_key, timeout, url_detection=URL_FACE_DETECTION ) + + def register_face(self, name: str, file_path: str): + """ + Register a face name to a file. + """ + + with open(file_path, "rb") as image: + response = post_image( + url=URL_FACE_REGISTRATION.format(self._ip_address, self._port), + image=image, + api_key=self._api_key, + timeout=self._timeout, + data={"userid": name}, + ) + + if response.status_code == 200 and response.json()["success"] == True: + print("Taught face {} using file {}".format(name, file_path)) + elif response.status_code == 200 and response.json()["success"] == False: + error = response.json()["error"] + print("Error: {}".format(error)) diff --git a/tests/test_deepstack.py b/tests/test_deepstack.py index 9d32804..6b7d825 100644 --- a/tests/test_deepstack.py +++ b/tests/test_deepstack.py @@ -13,7 +13,7 @@ MOCK_API_KEY = "mock_api_key" MOCK_TIMEOUT = 8 -MOCK_RESPONSE = { +MOCK_OBJECT_DETECTION_RESPONSE = { "success": True, "predictions": [ { @@ -43,19 +43,19 @@ ], } -MOCK_PREDICTIONS = MOCK_RESPONSE["predictions"] -MOCK_CONFIDENCES = [0.6998661, 0.7996547] +MOCK_OBJECT_PREDICTIONS = MOCK_OBJECT_DETECTION_RESPONSE["predictions"] +MOCK_OBJECT_CONFIDENCES = [0.6998661, 0.7996547] CONFIDENCE_THRESHOLD = 0.7 def test_DeepstackObject_process_image_bytes(): """Test a good response from server.""" with requests_mock.Mocker() as mock_req: - mock_req.post(MOCK_URL, status_code=ds.HTTP_OK, json=MOCK_RESPONSE) + mock_req.post(MOCK_URL, status_code=ds.HTTP_OK, json=MOCK_OBJECT_DETECTION_RESPONSE) dsobject = ds.DeepstackObject(MOCK_IP_ADDRESS, MOCK_PORT) dsobject.process_image_bytes(MOCK_BYTES) - assert dsobject.predictions == MOCK_PREDICTIONS + assert dsobject.predictions == MOCK_OBJECT_PREDICTIONS def test_DeepstackObject_process_image_bytes_timeout(): @@ -69,27 +69,27 @@ def test_DeepstackObject_process_image_bytes_timeout(): assert "SHOULD FAIL" in str(excinfo.value) -def test_get_object_labels(): +def test_get_objects(): """Cant always be sure order of returned list items.""" - object_labels = ds.get_object_labels(MOCK_PREDICTIONS) - assert type(object_labels) is list - assert "dog" in object_labels - assert "person" in object_labels - assert len(object_labels) == 2 + objects = ds.get_objects(MOCK_OBJECT_PREDICTIONS) + assert type(objects) is list + assert "dog" in objects + assert "person" in objects + assert len(objects) == 2 def test_get_objects_summary(): - objects_summary = ds.get_objects_summary(MOCK_PREDICTIONS) + objects_summary = ds.get_objects_summary(MOCK_OBJECT_PREDICTIONS) assert objects_summary == {"dog": 1, "person": 2} -def test_get_label_confidences(): - label_confidences = ds.get_label_confidences(MOCK_PREDICTIONS, "person") - assert label_confidences == MOCK_CONFIDENCES +def test_get_object_confidences(): + object_confidences = ds.get_object_confidences(MOCK_OBJECT_PREDICTIONS, "person") + assert object_confidences == MOCK_OBJECT_CONFIDENCES def test_get_confidences_above_threshold(): assert ( - len(ds.get_confidences_above_threshold(MOCK_CONFIDENCES, CONFIDENCE_THRESHOLD)) + len(ds.get_confidences_above_threshold(MOCK_OBJECT_CONFIDENCES, CONFIDENCE_THRESHOLD)) == 1 ) diff --git a/usage-face-recognition.ipynb b/usage-face-recognition.ipynb index 3c3ce60..591ec61 100644 --- a/usage-face-recognition.ipynb +++ b/usage-face-recognition.ipynb @@ -89,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -118,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -136,7 +136,7 @@ " 'x_max': 1199}]" ] }, - "execution_count": 8, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -147,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -156,7 +156,7 @@ "2" ] }, - "execution_count": 11, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -165,6 +165,52 @@ "len(dsface.predictions)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Register a face" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Taught face idris using file tests/images/couple.jpg\n" + ] + } + ], + "source": [ + "dsface.register_face(name=\"idris\", file_path = 'tests/images/couple.jpg')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "ename": "FileNotFoundError", + "evalue": "[Errno 2] No such file or directory: 'tests/images/couplesdf.jpg'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\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", + "\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", + "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'tests/images/couplesdf.jpg'" + ] + } + ], + "source": [ + "dsface.register_face(name=\"idris\", file_path = 'tests/images/couplesdf.jpg')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -173,6 +219,17 @@ "The package provides helper functions for extracting info out of deepstack predictions" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "name=\"idris\"\n", + "file_path=\"foo.jpg\"\n", + "print(\"Taught face {} using file {}\".format(name, file_path))" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/usage-object-detection.ipynb b/usage-object-detection.ipynb index 28b932e..47807ff 100644 --- a/usage-object-detection.ipynb +++ b/usage-object-detection.ipynb @@ -106,7 +106,6 @@ "#%%time\n", "try:\n", " dsobject.process_file(image_path)\n", - " print(dsobject.predictions)\n", "except ds.DeepstackException as exc:\n", " print(exc)" ] From 11b20809ab8558cf60b7e11e1e3e1d749fdde446 Mon Sep 17 00:00:00 2001 From: Robin Cole Date: Sat, 14 Sep 2019 09:22:05 +0100 Subject: [PATCH 2/5] Remove file handling --- README.md | 2 +- deepstack/core.py | 32 ++++++++++++++------------------ tests/test_deepstack.py | 18 ++++++++++++------ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index fb8c74c..aa634be 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,4 @@ TODO: add face registration and recognition. * Use `venv` -> `source venv/bin/activate` * `pip install -r requirements-dev.txt` * Run tests with `venv/bin/pytest tests/*` -* Black format with `venv/bin/black deepstack/core.py` +* Black format with `venv/bin/black deepstack/core.py` and `venv/bin/black tests/test_deepstack.py` diff --git a/deepstack/core.py b/deepstack/core.py index 10cf2ed..8ce07fe 100644 --- a/deepstack/core.py +++ b/deepstack/core.py @@ -59,12 +59,14 @@ def get_objects_summary(predictions: List[Dict]): } -def post_image(url: str, image: bytes, api_key: str, timeout: int, data: dict = {}): +def post_image( + url: str, image_bytes: bytes, api_key: str, timeout: int, data: dict = {} +): """Post an image to Deepstack.""" try: data["api_key"] = api_key response = requests.post( - url, files={"image": image}, data=data, timeout=timeout + url, files={"image": image_bytes}, data=data, timeout=timeout ) return response except requests.exceptions.Timeout: @@ -96,13 +98,8 @@ def __init__( self._timeout = timeout self._predictions = [] - def process_file(self, file_path: str): - """Process an image file.""" - with open(file_path, "rb") as image_bytes: - self.process_image_bytes(image_bytes) - - def process_image_bytes(self, image_bytes: bytes): - """Process an image, performing detection.""" + def detect(self, image_bytes: bytes): + """Process image_bytes, performing detection.""" self._predictions = [] url = self._url_detection.format(self._ip_address, self._port) @@ -150,19 +147,18 @@ def __init__( ip_address, port, api_key, timeout, url_detection=URL_FACE_DETECTION ) - def register_face(self, name: str, file_path: str): + def register_face(self, name: str, image_bytes: bytes): """ Register a face name to a file. """ - with open(file_path, "rb") as image: - response = post_image( - url=URL_FACE_REGISTRATION.format(self._ip_address, self._port), - image=image, - api_key=self._api_key, - timeout=self._timeout, - data={"userid": name}, - ) + response = post_image( + url=URL_FACE_REGISTRATION.format(self._ip_address, self._port), + image_bytes=image_bytes, + api_key=self._api_key, + timeout=self._timeout, + data={"userid": name}, + ) if response.status_code == 200 and response.json()["success"] == True: print("Taught face {} using file {}".format(name, file_path)) diff --git a/tests/test_deepstack.py b/tests/test_deepstack.py index 6b7d825..c9367dd 100644 --- a/tests/test_deepstack.py +++ b/tests/test_deepstack.py @@ -48,23 +48,25 @@ CONFIDENCE_THRESHOLD = 0.7 -def test_DeepstackObject_process_image_bytes(): +def test_DeepstackObject_detect(): """Test a good response from server.""" with requests_mock.Mocker() as mock_req: - mock_req.post(MOCK_URL, status_code=ds.HTTP_OK, json=MOCK_OBJECT_DETECTION_RESPONSE) + mock_req.post( + MOCK_URL, status_code=ds.HTTP_OK, json=MOCK_OBJECT_DETECTION_RESPONSE + ) dsobject = ds.DeepstackObject(MOCK_IP_ADDRESS, MOCK_PORT) - dsobject.process_image_bytes(MOCK_BYTES) + dsobject.detect(MOCK_BYTES) assert dsobject.predictions == MOCK_OBJECT_PREDICTIONS -def test_DeepstackObject_process_image_bytes_timeout(): +def test_DeepstackObject_detect_timeout(): """Test a timeout. THIS SHOULD FAIL""" with pytest.raises(ds.DeepstackException) as excinfo: with requests_mock.Mocker() as mock_req: mock_req.post(MOCK_URL, exc=requests.exceptions.ConnectTimeout) dsobject = ds.DeepstackObject(MOCK_IP_ADDRESS, MOCK_PORT) - dsobject.process_image_bytes(MOCK_BYTES) + dsobject.detect(MOCK_BYTES) assert False assert "SHOULD FAIL" in str(excinfo.value) @@ -90,6 +92,10 @@ def test_get_object_confidences(): def test_get_confidences_above_threshold(): assert ( - len(ds.get_confidences_above_threshold(MOCK_OBJECT_CONFIDENCES, CONFIDENCE_THRESHOLD)) + len( + ds.get_confidences_above_threshold( + MOCK_OBJECT_CONFIDENCES, CONFIDENCE_THRESHOLD + ) + ) == 1 ) From 6618b5cc71297c1585aff8a66757bf424de17e4c Mon Sep 17 00:00:00 2001 From: Robin Cole Date: Sat, 14 Sep 2019 09:36:16 +0100 Subject: [PATCH 3/5] Update notebooks --- README.md | 12 +++--- deepstack/core.py | 4 +- usage-face-recognition.ipynb | 64 ++++++++++---------------------- usage-object-detection.ipynb | 71 +++++++++++------------------------- 4 files changed, 50 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index aa634be..9fd93c7 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ # deepstack-python Unofficial python API for [DeepStack](https://python.deepstack.cc/). Provides class for making requests to the object detection endpoint, and functions for processing the result. See the Jupyter notebooks for usage. - -## Services -Face and object detection endpoints return bounding boxes of faces and objects respectively. - -TODO: add face registration and recognition. +Run deepstack (CPU, noAVX mode): +``` +docker run -e VISION-DETECTION=True -e VISION-FACE=True -e MODE=High -d \ + -v localstorage:/datastore -p 5000:5000 \ + -e API-KEY="Mysecretkey" \ + --name deepstack deepquestai/deepstack:noavx +``` ## Development * Use `venv` -> `source venv/bin/activate` diff --git a/deepstack/core.py b/deepstack/core.py index 8ce07fe..df81d4d 100644 --- a/deepstack/core.py +++ b/deepstack/core.py @@ -161,7 +161,7 @@ def register_face(self, name: str, image_bytes: bytes): ) if response.status_code == 200 and response.json()["success"] == True: - print("Taught face {} using file {}".format(name, file_path)) + return elif response.status_code == 200 and response.json()["success"] == False: error = response.json()["error"] - print("Error: {}".format(error)) + raise DeepstackException(f"Error from Deepstack: {error}") diff --git a/usage-face-recognition.ipynb b/usage-face-recognition.ipynb index 591ec61..0a0b06d 100644 --- a/usage-face-recognition.ipynb +++ b/usage-face-recognition.ipynb @@ -4,15 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This package provides convenience classes and functions for working with deepstack face API. \n", - "\n", - "Run deepstack with:\n", - "```\n", - "docker run -e VISION-FACE=True -e MODE=High -d \\\n", - " -v localstorage:/datastore -p 5000:5000 \\\n", - " -e API-KEY=\"Mysecretkey\" \\\n", - " --name deepstack deepquestai/deepstack:noavx\n", - "```" + "Work with the deepstack face API. " ] }, { @@ -37,7 +29,7 @@ "IP_ADDRESS = 'localhost'\n", "PORT = '5000'\n", "API_KEY = \"Mysecretkey\"\n", - "TIMEOUT = 8" + "TIMEOUT = 10 # Default is 10" ] }, { @@ -96,15 +88,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "[{'confidence': 0.9999846, 'y_min': 162, 'x_min': 1620, 'y_max': 680, 'x_max': 1982}, {'confidence': 0.99997175, 'y_min': 230, 'x_min': 867, 'y_max': 729, 'x_max': 1199}]\n" + "CPU times: user 8.38 ms, sys: 9.7 ms, total: 18.1 ms\n", + "Wall time: 2.72 s\n" ] } ], "source": [ - "#%%time\n", + "%%time\n", "try:\n", - " dsface.process_file(image_path)\n", - " print(dsface.predictions)\n", + " with open(image_path, \"rb\") as image_bytes:\n", + " dsface.detect(image_bytes)\n", "except ds.DeepstackException as exc:\n", " print(exc)" ] @@ -174,41 +167,33 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Taught face idris using file tests/images/couple.jpg\n" + "CPU times: user 4.46 ms, sys: 3.62 ms, total: 8.09 ms\n", + "Wall time: 2.78 s\n" ] } ], "source": [ - "dsface.register_face(name=\"idris\", file_path = 'tests/images/couple.jpg')" + "%%time\n", + "try:\n", + " with open(image_path, \"rb\") as image_bytes:\n", + " dsface.register_face(\"idris\", image_bytes)\n", + "except ds.DeepstackException as exc:\n", + " print(exc)" ] }, { - "cell_type": "code", - "execution_count": 10, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "ename": "FileNotFoundError", - "evalue": "[Errno 2] No such file or directory: 'tests/images/couplesdf.jpg'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\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", - "\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", - "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'tests/images/couplesdf.jpg'" - ] - } - ], "source": [ - "dsface.register_face(name=\"idris\", file_path = 'tests/images/couplesdf.jpg')" + "## Face recognition\n", + "Recoginition will match any faces that have been taught. This is slower than face detection" ] }, { @@ -219,17 +204,6 @@ "The package provides helper functions for extracting info out of deepstack predictions" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "name=\"idris\"\n", - "file_path=\"foo.jpg\"\n", - "print(\"Taught face {} using file {}\".format(name, file_path))" - ] - }, { "cell_type": "code", "execution_count": null, diff --git a/usage-object-detection.ipynb b/usage-object-detection.ipynb index 47807ff..bccab27 100644 --- a/usage-object-detection.ipynb +++ b/usage-object-detection.ipynb @@ -4,17 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This package provides convenience classes and functions for working with deepstack object detection API.\n", - "\n", - "Run deepstack with:\n", - "```\n", - "docker run -e VISION-DETECTION=True -e MODE=High -d \\\n", - " -v localstorage:/datastore -p 5000:5000 \\\n", - " -e API-KEY=\"Mysecretkey\" \\\n", - " --name deepstack deepquestai/deepstack:noavx\n", - "```\n", - "\n", - "Note that by default, the minimum confidence for detected objects is 0.45" + "Work with the deepstack object detection API (Yolo-v3). Note that by default, the minimum confidence for detected objects is 0.45" ] }, { @@ -32,14 +22,14 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "IP_ADDRESS = 'localhost'\n", "PORT = '5000'\n", "API_KEY = \"Mysecretkey\"\n", - "TIMEOUT = 8" + "TIMEOUT = 10 # Default is 10" ] }, { @@ -86,26 +76,29 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Perform object detection" + "Perform object detection - can be slow" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "[{'confidence': 0.9998661, 'label': 'person', 'y_min': 0, 'x_min': 258, 'y_max': 676, 'x_max': 485}, {'confidence': 0.9996547, 'label': 'person', 'y_min': 0, 'x_min': 405, 'y_max': 652, 'x_max': 639}, {'confidence': 0.99745613, 'label': 'dog', 'y_min': 311, 'x_min': 624, 'y_max': 591, 'x_max': 825}]\n" + "Timeout connecting to Deepstack, current timeout is 8 seconds\n", + "CPU times: user 3.88 ms, sys: 2.42 ms, total: 6.3 ms\n", + "Wall time: 8.02 s\n" ] } ], "source": [ - "#%%time\n", + "%%time\n", "try:\n", - " dsobject.process_file(image_path)\n", + " with open(image_path, 'rb') as image_bytes:\n", + " dsobject.detect(image_bytes)\n", "except ds.DeepstackException as exc:\n", " print(exc)" ] @@ -156,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -165,7 +158,7 @@ "3" ] }, - "execution_count": 14, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -186,7 +179,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Get the set of unique labels" + "Get the set objects" ] }, { @@ -206,14 +199,14 @@ } ], "source": [ - "ds.get_object_labels(dsobject.predictions)" + "ds.get_objects(dsobject.predictions)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Get a summary of the number of occurances of labels" + "Get a summary of the number of occurances of objects" ] }, { @@ -237,31 +230,11 @@ "summary" ] }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['dog', 'person']" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "list(summary.keys())" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Get a list of confidences for a single label type, e.g. `person`" + "Get a list of confidences for a single object type, e.g. `person`" ] }, { @@ -281,8 +254,8 @@ } ], "source": [ - "confidences = ds.get_label_confidences(dsobject.predictions, 'person')\n", - "confidences" + "person_confidences = ds.get_object_confidences(dsobject.predictions, 'person')\n", + "person_confidences" ] }, { @@ -294,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -303,14 +276,14 @@ "1" ] }, - "execution_count": 16, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CONFIDENCE_THRESHOLD = 0.9997\n", - "len(ds.get_confidences_above_threshold(confidences, CONFIDENCE_THRESHOLD))" + "len(ds.get_confidences_above_threshold(person_confidences, CONFIDENCE_THRESHOLD))" ] }, { From c5d6bf5aeda7590025c309720ac0ca7f7566f48a Mon Sep 17 00:00:00 2001 From: Robin Cole Date: Sat, 14 Sep 2019 10:11:43 +0100 Subject: [PATCH 4/5] Adds tests --- deepstack/core.py | 31 ++++++++++ setup.py | 2 +- tests/test_deepstack.py | 30 ++++++++- usage-face-recognition.ipynb | 65 ++++++++++++++++--- usage-object-detection.ipynb | 117 +++++------------------------------ 5 files changed, 133 insertions(+), 112 deletions(-) diff --git a/deepstack/core.py b/deepstack/core.py index df81d4d..e51b0b2 100644 --- a/deepstack/core.py +++ b/deepstack/core.py @@ -30,6 +30,21 @@ def get_confidences_above_threshold( return [val for val in confidences if val >= confidence_threshold] +def get_recognised_faces(predictions: List[Dict]) -> List[Dict]: + """ + Get the recognised faces. + """ + try: + matched_faces = { + face["userid"]: round(face["confidence"] * 100, 1) + for face in predictions + if not face["userid"] == "unknown" + } + return matched_faces + except: + return {} + + def get_objects(predictions: List[Dict]) -> List[str]: """ Get a list of the unique objects predicted. @@ -73,6 +88,8 @@ def post_image( raise DeepstackException( f"Timeout connecting to Deepstack, current timeout is {timeout} seconds" ) + except requests.exceptions.ConnectionError as exc: + raise DeepstackException(f"Connection error: {exc}") class DeepstackException(Exception): @@ -165,3 +182,17 @@ def register_face(self, name: str, image_bytes: bytes): elif response.status_code == 200 and response.json()["success"] == False: error = response.json()["error"] raise DeepstackException(f"Error from Deepstack: {error}") + + def recognise(self, image_bytes: bytes): + """Process image_bytes, performing recognition.""" + self._predictions = [] + url = URL_FACE_RECOGNITION.format(self._ip_address, self._port) + + response = post_image(url, image_bytes, self._api_key, self._timeout) + + if response.status_code == HTTP_OK: + if response.json()["success"]: + self._predictions = response.json()["predictions"] + else: + error = response.json()["error"] + raise DeepstackException(f"Error from Deepstack: {error}") diff --git a/setup.py b/setup.py index 2b7ae87..3861349 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -VERSION = "0.3" +VERSION = "0.4" REQUIRES = ["requests"] diff --git a/tests/test_deepstack.py b/tests/test_deepstack.py index c9367dd..cc3db02 100644 --- a/tests/test_deepstack.py +++ b/tests/test_deepstack.py @@ -1,5 +1,3 @@ -# Placeholder - import deepstack.core as ds import requests import requests_mock @@ -43,9 +41,32 @@ ], } +MOCK_FACE_RECOGNITION_RESPONSE = { + "success": True, + "predictions": [ + { + "confidence": 0.74999994, + "userid": "Idris Elba", + "y_min": 176, + "x_min": 209, + "y_max": 825, + "x_max": 677, + }, + { + "confidence": 0, + "userid": "unknown", + "y_min": 230, + "x_min": 867, + "y_max": 729, + "x_max": 1199, + }, + ], +} + MOCK_OBJECT_PREDICTIONS = MOCK_OBJECT_DETECTION_RESPONSE["predictions"] MOCK_OBJECT_CONFIDENCES = [0.6998661, 0.7996547] CONFIDENCE_THRESHOLD = 0.7 +MOCK_RECOGNISED_FACES = {"Idris Elba": 75.0} def test_DeepstackObject_detect(): @@ -99,3 +120,8 @@ def test_get_confidences_above_threshold(): ) == 1 ) + + +def test_get_recognised_faces(): + predictions = MOCK_FACE_RECOGNITION_RESPONSE["predictions"] + assert ds.get_recognised_faces(predictions) == MOCK_RECOGNISED_FACES diff --git a/usage-face-recognition.ipynb b/usage-face-recognition.ipynb index 0a0b06d..597ecb6 100644 --- a/usage-face-recognition.ipynb +++ b/usage-face-recognition.ipynb @@ -76,7 +76,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Perform face detection" + "## Face detection\n", + "Detect faces, but do not recognise them, quite fast." ] }, { @@ -88,8 +89,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 8.38 ms, sys: 9.7 ms, total: 18.1 ms\n", - "Wall time: 2.72 s\n" + "CPU times: user 9.38 ms, sys: 9.2 ms, total: 18.6 ms\n", + "Wall time: 2.44 s\n" ] } ], @@ -162,27 +163,28 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Register a face" + "## Register a face\n", + "Post a name and a close up photo of a face" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 4.46 ms, sys: 3.62 ms, total: 8.09 ms\n", - "Wall time: 2.78 s\n" + "CPU times: user 5.12 ms, sys: 7.95 ms, total: 13.1 ms\n", + "Wall time: 3.13 s\n" ] } ], "source": [ "%%time\n", "try:\n", - " with open(image_path, \"rb\") as image_bytes:\n", + " with open('tests/images/idris.jpg', \"rb\") as image_bytes:\n", " dsface.register_face(\"idris\", image_bytes)\n", "except ds.DeepstackException as exc:\n", " print(exc)" @@ -196,12 +198,57 @@ "Recoginition will match any faces that have been taught. This is slower than face detection" ] }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 4.63 ms, sys: 2.9 ms, total: 7.53 ms\n", + "Wall time: 4.24 s\n" + ] + } + ], + "source": [ + "%%time\n", + "try:\n", + " with open(image_path, \"rb\") as image_bytes:\n", + " dsface.recognise(image_bytes)\n", + "except ds.DeepstackException as exc:\n", + " print(exc)" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Helper functions\n", - "The package provides helper functions for extracting info out of deepstack predictions" + "The package provides helper functions for extracting info out of deepstack predictions.\n", + "\n", + "Get recognised faces and their probability (%)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Idris Elba': 74.7}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ds.get_recognised_faces(dsface.predictions)" ] }, { diff --git a/usage-object-detection.ipynb b/usage-object-detection.ipynb index bccab27..a5e709c 100644 --- a/usage-object-detection.ipynb +++ b/usage-object-detection.ipynb @@ -22,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -81,16 +81,16 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Timeout connecting to Deepstack, current timeout is 8 seconds\n", - "CPU times: user 3.88 ms, sys: 2.42 ms, total: 6.3 ms\n", - "Wall time: 8.02 s\n" + "Timeout connecting to Deepstack, current timeout is 10 seconds\n", + "CPU times: user 3.67 ms, sys: 1.88 ms, total: 5.55 ms\n", + "Wall time: 10 s\n" ] } ], @@ -112,57 +112,18 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'confidence': 0.9998661,\n", - " 'label': 'person',\n", - " 'y_min': 0,\n", - " 'x_min': 258,\n", - " 'y_max': 676,\n", - " 'x_max': 485},\n", - " {'confidence': 0.9996547,\n", - " 'label': 'person',\n", - " 'y_min': 0,\n", - " 'x_min': 405,\n", - " 'y_max': 652,\n", - " 'x_max': 639},\n", - " {'confidence': 0.99745613,\n", - " 'label': 'dog',\n", - " 'y_min': 311,\n", - " 'x_min': 624,\n", - " 'y_max': 591,\n", - " 'x_max': 825}]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "dsobject.predictions" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "len(dsobject.predictions)" ] @@ -184,20 +145,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['dog', 'person']" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "ds.get_objects(dsobject.predictions)" ] @@ -211,20 +161,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'dog': 1, 'person': 2}" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "summary = ds.get_objects_summary(dsobject.predictions)\n", "summary" @@ -239,20 +178,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[0.9998661, 0.9996547]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "person_confidences = ds.get_object_confidences(dsobject.predictions, 'person')\n", "person_confidences" @@ -267,20 +195,9 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "CONFIDENCE_THRESHOLD = 0.9997\n", "len(ds.get_confidences_above_threshold(person_confidences, CONFIDENCE_THRESHOLD))" From 8677edf4582d97dc01e91ebffb6f1b0d56d5fa05 Mon Sep 17 00:00:00 2001 From: Robin Cole Date: Sat, 14 Sep 2019 10:16:19 +0100 Subject: [PATCH 5/5] Update notebooks --- usage-face-recognition.ipynb | 40 +++++------ usage-object-detection.ipynb | 124 +++++++++++++++++++++++++++++------ 2 files changed, 123 insertions(+), 41 deletions(-) diff --git a/usage-face-recognition.ipynb b/usage-face-recognition.ipynb index 597ecb6..ca71c3f 100644 --- a/usage-face-recognition.ipynb +++ b/usage-face-recognition.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -22,14 +22,14 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "IP_ADDRESS = 'localhost'\n", "PORT = '5000'\n", "API_KEY = \"Mysecretkey\"\n", - "TIMEOUT = 10 # Default is 10" + "TIMEOUT = 30 # Default is 10" ] }, { @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -82,15 +82,15 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 9.38 ms, sys: 9.2 ms, total: 18.6 ms\n", - "Wall time: 2.44 s\n" + "CPU times: user 5.04 ms, sys: 7.95 ms, total: 13 ms\n", + "Wall time: 3.01 s\n" ] } ], @@ -112,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -130,7 +130,7 @@ " 'x_max': 1199}]" ] }, - "execution_count": 6, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -141,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -150,7 +150,7 @@ "2" ] }, - "execution_count": 7, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -169,15 +169,15 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 5.12 ms, sys: 7.95 ms, total: 13.1 ms\n", - "Wall time: 3.13 s\n" + "CPU times: user 4.81 ms, sys: 9.05 ms, total: 13.9 ms\n", + "Wall time: 2.99 s\n" ] } ], @@ -200,15 +200,15 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 4.63 ms, sys: 2.9 ms, total: 7.53 ms\n", - "Wall time: 4.24 s\n" + "CPU times: user 4.37 ms, sys: 2.84 ms, total: 7.21 ms\n", + "Wall time: 3.87 s\n" ] } ], @@ -233,7 +233,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -242,7 +242,7 @@ "{'Idris Elba': 74.7}" ] }, - "execution_count": 11, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } diff --git a/usage-object-detection.ipynb b/usage-object-detection.ipynb index a5e709c..e9bd621 100644 --- a/usage-object-detection.ipynb +++ b/usage-object-detection.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -22,14 +22,14 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "IP_ADDRESS = 'localhost'\n", "PORT = '5000'\n", "API_KEY = \"Mysecretkey\"\n", - "TIMEOUT = 10 # Default is 10" + "TIMEOUT = 20 # Default is 10" ] }, { @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -81,16 +81,15 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Timeout connecting to Deepstack, current timeout is 10 seconds\n", - "CPU times: user 3.67 ms, sys: 1.88 ms, total: 5.55 ms\n", - "Wall time: 10 s\n" + "CPU times: user 5.14 ms, sys: 3.16 ms, total: 8.3 ms\n", + "Wall time: 13.6 s\n" ] } ], @@ -112,18 +111,57 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'confidence': 0.9998661,\n", + " 'label': 'person',\n", + " 'y_min': 0,\n", + " 'x_min': 258,\n", + " 'y_max': 676,\n", + " 'x_max': 485},\n", + " {'confidence': 0.9996547,\n", + " 'label': 'person',\n", + " 'y_min': 0,\n", + " 'x_min': 405,\n", + " 'y_max': 652,\n", + " 'x_max': 639},\n", + " {'confidence': 0.99745613,\n", + " 'label': 'dog',\n", + " 'y_min': 311,\n", + " 'x_min': 624,\n", + " 'y_max': 591,\n", + " 'x_max': 825}]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "dsobject.predictions" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "len(dsobject.predictions)" ] @@ -145,9 +183,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['dog', 'person']" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ds.get_objects(dsobject.predictions)" ] @@ -161,9 +210,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dog': 1, 'person': 2}" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "summary = ds.get_objects_summary(dsobject.predictions)\n", "summary" @@ -178,9 +238,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[0.9998661, 0.9996547]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "person_confidences = ds.get_object_confidences(dsobject.predictions, 'person')\n", "person_confidences" @@ -195,9 +266,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "CONFIDENCE_THRESHOLD = 0.9997\n", "len(ds.get_confidences_above_threshold(person_confidences, CONFIDENCE_THRESHOLD))"