Skip to content

Commit

Permalink
add ! validate image size
Browse files Browse the repository at this point in the history
  • Loading branch information
vitali-yanushchyk-valor committed Oct 25, 2024
1 parent 77e832e commit ed6ac45
Show file tree
Hide file tree
Showing 24 changed files with 34 additions and 24 deletions.
3 changes: 0 additions & 3 deletions src/hope_dedup_engine/apps/api/admin/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,3 @@ def has_add_permission(self, request):

def has_change_permission(self, request, obj=None):
return False

def has_delete_permission(self, request, obj=None):
return obj is not None
7 changes: 4 additions & 3 deletions src/hope_dedup_engine/apps/api/deduplication/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,11 @@ def find_duplicates(deduplication_set_id: str, serialized_lock: str) -> None:
deduplication_set.state = deduplication_set.State.CLEAN
deduplication_set.save()

if lock_enabled:
lock.release()

except Exception:
deduplication_set.state = DeduplicationSet.State.ERROR
deduplication_set.save()
raise

finally:
if lock_enabled:
lock.release()
9 changes: 9 additions & 0 deletions src/hope_dedup_engine/apps/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@ class DownloaderKeyError(Exception):
def __init__(self, key: str) -> None:
self.key = key
super().__init__(f"Downloader key '{key}' does not exist.")


class NotCompliantImageError(Exception):
"""
Exception raised when an image is not compliant with the expected parameters.
"""

def __init__(self, message: str) -> None:
super().__init__(message)
27 changes: 15 additions & 12 deletions src/hope_dedup_engine/apps/faces/services/image_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import numpy as np
from constance import config

from hope_dedup_engine.apps.core.exceptions import NotCompliantImageError
from hope_dedup_engine.apps.faces.managers import DNNInferenceManager, StorageManager


Expand Down Expand Up @@ -97,19 +98,19 @@ def _get_face_detections_dnn(
# Decode image from binary buffer to 3D numpy array (height, width, channels of BlueGreeRed color space)
image = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
(h, w) = image.shape[:2]
_h, _w = (
self.blob_from_image_cfg.shape["height"],
self.blob_from_image_cfg.shape["width"],
)
if h < _h or w < _w:
raise NotCompliantImageError(
f"Image {filename} too small: '{h}x{w}'. It needs to be at least '{_h}x{_w}'."
)

# Create a blob (4D tensor) from the image
blob = cv2.dnn.blobFromImage(
image=cv2.resize(
image,
dsize=(
self.blob_from_image_cfg.shape["height"],
self.blob_from_image_cfg.shape["width"],
),
),
size=(
self.blob_from_image_cfg.shape["height"],
self.blob_from_image_cfg.shape["width"],
),
image=cv2.resize(image, dsize=(_h, _w)),
size=(_h, _w),
scalefactor=self.blob_from_image_cfg.scale_factor,
mean=self.blob_from_image_cfg.mean_values,
)
Expand Down Expand Up @@ -161,7 +162,9 @@ def encode_face(self, filename: str, encodings_filename: str) -> None:
encodings: list[np.ndarray[np.float32, Any]] = []
face_regions = self._get_face_detections_dnn(filename)
if not face_regions:
self.logger.warning("No face regions detected in image %s", filename)
raise NotCompliantImageError(
f"No face regions detected in image '{filename}'."
)
else:

for region in face_regions:
Expand Down
2 changes: 1 addition & 1 deletion src/hope_dedup_engine/config/fragments/constance.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
int,
),
"FACE_ENCODINGS_MODEL": (
"small",
"large",
"""
Specifies the model type used for encoding face landmarks. It can be either 'small' which is faster and
detects only 5 key facial landmarks, or 'large' which is more precise and identifies 68 key facial landmarks
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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 tests/extras/demoapp/demo_images/2781_V.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 tests/extras/demoapp/demo_images/370_C.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 modified tests/extras/demoapp/demo_images/Aaron_Eckhart_0001.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 modified tests/extras/demoapp/demo_images/Aaron_Guiel_0001.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 modified tests/extras/demoapp/demo_images/Aaron_Peirsol_0001.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 modified tests/extras/demoapp/demo_images/Aaron_Peirsol_0002.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 modified tests/extras/demoapp/demo_images/Cathy_Freeman_0001.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 modified tests/extras/demoapp/demo_images/Cathy_Freeman_0002.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/extras/demoapp/demo_images/Ziwang_Xu_0001.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 modified tests/extras/demoapp/demo_images/Zoe_Ball_0001.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 added tests/extras/demoapp/demo_images/too_small.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 modified tests/extras/demoapp/demo_images/without_face.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tests/faces/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def mock_image_processor(
@pytest.fixture
def image_bytes_io():
img_byte_arr = BytesIO()
image = Image.new("RGB", (100, 100), color="red")
image = Image.new("RGB", (300, 300), color="red")
image.save(img_byte_arr, format="JPEG")
img_byte_arr.seek(0)
img_byte_arr.fake_open = lambda *_: BytesIO(img_byte_arr.getvalue())
Expand Down
8 changes: 4 additions & 4 deletions tests/faces/faces_const.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
}
FACE_REGIONS_INVALID: Final[list[list[tuple[int, int, int, int]]]] = [[], [(0, 0, 10)]]
FACE_REGIONS_VALID: Final[list[tuple[int, int, int, int]]] = [
(10, 10, 20, 20),
(30, 30, 40, 40),
(40, 40, 80, 80),
(120, 120, 160, 160),
]
BLOB_FROM_IMAGE_SCALE_FACTOR: Final[float] = 1.0
BLOB_FROM_IMAGE_MEAN_VALUES: Final[tuple[float, float, float]] = (104.0, 177.0, 123.0)
Expand All @@ -56,8 +56,8 @@
(0, 0, 0.15, 0.1, 0.1, 0.2, 0.2), # with confidence 0.15 -> invalid detection
]
IMAGE_SIZE: Final[tuple[int, int, int]] = (
100,
100,
400,
400,
3,
) # Size of the image after decoding (h, w, number of channels)
RESIZED_IMAGE_SIZE: Final[tuple[int, int, int]] = (
Expand Down

0 comments on commit ed6ac45

Please sign in to comment.