Skip to content

Commit 381e691

Browse files
committed
Progress
1 parent a335ab2 commit 381e691

File tree

7 files changed

+30
-19
lines changed

7 files changed

+30
-19
lines changed

docs/source/differences-to-vws.rst

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,13 @@ Image quality and ratings
2929
-------------------------
3030

3131
Targets are assigned a rating between 0 and 5 of how good they are for tracking purposes.
32-
In the mock this is a random number between 0 and 5.
32+
In the mock this is calculated from the image quality, differently to how Vuforia does this.
3333

3434
Image targets which are not suited to detection are given 'failed' statuses.
3535
The criteria for these images is not defined by the Vuforia documentation.
3636
The mock is more forgiving than the real Vuforia Web Services.
3737
Therefore, an image given a 'success' status by the mock may not be given a 'success' status by the real Vuforia Web Services.
3838

39-
When updating an image for a target on the real Vuforia Web Services, the rating may stay the same.
40-
The mock changes the rating for a target to a different random number when the image is changed.
41-
4239
Matching targets in the processing state
4340
----------------------------------------
4441

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ warn_untyped_fields = true
140140
[[tool.mypy.overrides]]
141141

142142
module = [
143+
"brisque",
143144
"docker",
144145
"docker.errors",
145146
"docker.models.networks",
@@ -250,8 +251,10 @@ readme = { file = "README.rst", content-type = "text/x-rst"}
250251
requires-python = ">=3.10"
251252
dependencies = [
252253
"Pillow",
254+
"brisque",
253255
"flask",
254256
"multipart",
257+
"numpy",
255258
"pydantic",
256259
"requests",
257260
"requests-mock",
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
FROM python:3.11-slim-buster
2+
RUN apt update && apt install -y gcc g++ libgl1-mesa-glx libglib2.0-0
23
# We set this pretend version as we do not have Git in our path, and we do
34
# not care enough about having the version correct inside the Docker container
45
# to install it.
56
ENV SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0
67
ENV TARGET_MANAGER_HOST=0.0.0.0
78
COPY . /app
89
WORKDIR /app
9-
RUN pip install .
10+
RUN pip install --upgrade .
1011
EXPOSE 5000
1112
ENTRYPOINT ["python"]
1213
CMD ["src/mock_vws/_flask_server/target_manager.py"]
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
FROM python:3.11-slim-buster
2+
RUN apt update && apt install -y gcc g++ libgl1-mesa-glx libglib2.0-0
23
# We set this pretend version as we do not have Git in our path, and we do
34
# not care enough about having the version correct inside the Docker container
45
# to install it.
56
ENV SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0
67
ENV VWQ_HOST=0.0.0.0
78
COPY . /app
89
WORKDIR /app
9-
RUN pip install .
10+
RUN pip install --upgrade .
1011
EXPOSE 5000
1112
ENTRYPOINT ["python"]
1213
CMD ["src/mock_vws/_flask_server/vwq.py"]
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
FROM python:3.11-slim-buster
2+
RUN apt update && apt install -y gcc g++ libgl1-mesa-glx libglib2.0-0
23
COPY . /app
34
# We set this pretend version as we do not have Git in our path, and we do
45
# not care enough about having the version correct inside the Docker container
56
# to install it.
67
ENV SETUPTOOLS_SCM_PRETEND_VERSION=0.0.0
78
ENV VWS_HOST=0.0.0.0
89
WORKDIR /app
9-
RUN pip install .
10+
RUN pip install --upgrade .
1011
EXPOSE 5000
1112
ENTRYPOINT ["python"]
1213
CMD ["src/mock_vws/_flask_server/vws.py"]

src/mock_vws/_requests_mock_server/mock_web_services_api.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,6 @@ def update_target(
589589
context.status_code = fail_exception.status_code
590590
return fail_exception.response_text
591591

592-
# TODO: Consider the case of the code that was here
593-
594592
gmt = ZoneInfo("GMT")
595593
last_modified_date = datetime.datetime.now(tz=gmt)
596594

src/mock_vws/target.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import base64
77
import datetime
88
import io
9-
import random
9+
import math
1010
import statistics
1111
import uuid
1212
from dataclasses import dataclass, field
1313
from typing import TypedDict
1414
from zoneinfo import ZoneInfo
1515

16+
import brisque
17+
import numpy as np
1618
from PIL import Image, ImageStat
1719

1820
from mock_vws._constants import TargetStatuses
@@ -28,7 +30,6 @@ class TargetDict(TypedDict):
2830
image_base64: str
2931
active_flag: bool
3032
processing_time_seconds: int | float
31-
processed_tracking_rating: int
3233
application_metadata: str | None
3334
target_id: str
3435
last_modified_date: str
@@ -51,11 +52,24 @@ def _time_now() -> datetime.datetime:
5152
return datetime.datetime.now(tz=gmt)
5253

5354

54-
def _random_tracking_rating() -> int:
55+
def _quality(image_content: bytes) -> int:
5556
"""
56-
Return a random tracking rating.
57+
Args:
58+
image_content: The image content.
59+
60+
Returns:
61+
The quality of the image.
5762
"""
58-
return random.randint(0, 5)
63+
image_file = io.BytesIO(initial_bytes=image_content)
64+
image = Image.open(fp=image_file)
65+
image_array = np.asarray(a=image)
66+
obj = brisque.BRISQUE(url=False)
67+
# We avoid a barrage of warnings from the BRISQUE library.
68+
with np.errstate(divide="ignore", invalid="ignore"):
69+
score = obj.score(img=image_array)
70+
if math.isnan(score):
71+
return 0
72+
return int(score / 20)
5973

6074

6175
@dataclass(frozen=True, eq=True)
@@ -75,9 +89,6 @@ class Target:
7589
delete_date: datetime.datetime | None = None
7690
last_modified_date: datetime.datetime = field(default_factory=_time_now)
7791
previous_month_recos: int = 0
78-
processed_tracking_rating: int = field(
79-
default_factory=_random_tracking_rating,
80-
)
8192
reco_rating: str = ""
8293
target_id: str = field(default_factory=_random_hex)
8394
total_recos: int = 0
@@ -158,7 +169,7 @@ def tracking_rating(self) -> int:
158169
return -1
159170

160171
if self._post_processing_status == TargetStatuses.SUCCESS:
161-
return self.processed_tracking_rating
172+
return _quality(image_content=self.image_value)
162173

163174
return 0
164175

@@ -219,7 +230,6 @@ def to_dict(self) -> TargetDict:
219230
"image_base64": image_base64,
220231
"active_flag": self.active_flag,
221232
"processing_time_seconds": self.processing_time_seconds,
222-
"processed_tracking_rating": self.processed_tracking_rating,
223233
"application_metadata": self.application_metadata,
224234
"target_id": self.target_id,
225235
"last_modified_date": self.last_modified_date.isoformat(),

0 commit comments

Comments
 (0)