Skip to content
This repository was archived by the owner on Mar 19, 2023. It is now read-only.

Commit 0a124ad

Browse files
authored
Merge pull request #271 from wizmo2/crop_roi
add crop_roi option
2 parents e96d21a + c013f56 commit 0a124ad

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ image_processing:
3737
roi_x_max: 0.8
3838
#roi_y_min: 0.4
3939
roi_y_max: 0.8
40+
crop_to_roi: True
4041
targets:
4142
- target: person
4243
- target: vehicle
@@ -64,6 +65,7 @@ Configuration variables:
6465
- **roi_x_max**: (optional, default 1), range 0-1, must be more than roi_x_min
6566
- **roi_y_min**: (optional, default 0), range 0-1, must be less than roi_y_max
6667
- **roi_y_max**: (optional, default 1), range 0-1, must be more than roi_y_min
68+
- **crop_to_roi**: (optional, default False), crops the image to the specified roi. May improve object detection accuracy when a region-of-interest is applied
6769
- **source**: Must be a camera.
6870
- **targets**: The list of target object names and/or `object_type`, default `person`. Optionally a `confidence` can be set for this target, if not the default confidence is used. Note the minimum possible confidence is 10%.
6971

custom_components/deepstack_object/image_processing.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
CONF_ROI_X_MAX = "roi_x_max"
7878
CONF_SCALE = "scale"
7979
CONF_CUSTOM_MODEL = "custom_model"
80+
CONF_CROP_ROI = "crop_to_roi"
8081

8182
DATETIME_FORMAT = "%Y-%m-%d_%H-%M-%S-%f"
8283
DEFAULT_API_KEY = ""
@@ -138,6 +139,7 @@
138139
vol.Optional(CONF_SAVE_TIMESTAMPTED_FILE, default=False): cv.boolean,
139140
vol.Optional(CONF_ALWAYS_SAVE_LATEST_FILE, default=False): cv.boolean,
140141
vol.Optional(CONF_SHOW_BOXES, default=True): cv.boolean,
142+
vol.Optional(CONF_CROP_ROI, default=False): cv.boolean,
141143
}
142144
)
143145

@@ -237,6 +239,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
237239
save_file_format=config[CONF_SAVE_FILE_FORMAT],
238240
save_timestamped_file=config.get(CONF_SAVE_TIMESTAMPTED_FILE),
239241
always_save_latest_file=config.get(CONF_ALWAYS_SAVE_LATEST_FILE),
242+
crop_roi=config[CONF_CROP_ROI],
240243
camera_entity=camera.get(CONF_ENTITY_ID),
241244
name=camera.get(CONF_NAME),
242245
)
@@ -266,6 +269,7 @@ def __init__(
266269
save_file_format,
267270
save_timestamped_file,
268271
always_save_latest_file,
272+
crop_roi,
269273
camera_entity,
270274
name=None,
271275
):
@@ -307,6 +311,7 @@ def __init__(
307311
"y_max": roi_y_max,
308312
"x_max": roi_x_max,
309313
}
314+
self._crop_roi = crop_roi
310315
self._scale = scale
311316
self._show_boxes = show_boxes
312317
self._image_width = None
@@ -322,7 +327,24 @@ def process_image(self, image):
322327
"""Process an image."""
323328
self._image = Image.open(io.BytesIO(bytearray(image)))
324329
self._image_width, self._image_height = self._image.size
325-
330+
# scale to roi
331+
if self._crop_roi:
332+
roi = (
333+
self._image_width * self._roi_dict["x_min"],
334+
self._image_height * self._roi_dict["y_min"],
335+
self._image_width * (self._roi_dict["x_max"]),
336+
self._image_height * (self._roi_dict["y_max"])
337+
)
338+
self._image = self._image.crop(roi)
339+
self._image_width, self._image_height = self._image.size
340+
with io.BytesIO() as output:
341+
self._image.save(output, format="JPEG")
342+
image = output.getvalue()
343+
_LOGGER.debug(
344+
(
345+
f"Image cropped with : {self._roi_dict} W={self._image_width} H={self._image_height}"
346+
)
347+
)
326348
# resize image if different then default
327349
if self._scale != DEAULT_SCALE:
328350
newsize = (self._image_width * self._scale, self._image_width * self._scale)
@@ -368,7 +390,7 @@ def process_image(self, image):
368390
if obj["name"] == target[CONF_TARGET]:
369391
confidence = target[CONF_CONFIDENCE]
370392
if obj["confidence"] > confidence:
371-
if not object_in_roi(self._roi_dict, obj["centroid"]):
393+
if not self._crop_roi and not object_in_roi(self._roi_dict, obj["centroid"]):
372394
continue
373395
self._targets_found.append(obj)
374396

@@ -457,7 +479,7 @@ def save_image(self, targets, directory) -> str:
457479
draw = ImageDraw.Draw(img)
458480

459481
roi_tuple = tuple(self._roi_dict.values())
460-
if roi_tuple != DEFAULT_ROI and self._show_boxes:
482+
if roi_tuple != DEFAULT_ROI and self._show_boxes and not self._crop_roi:
461483
draw_box(
462484
draw,
463485
roi_tuple,

custom_components/deepstack_object/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"domain": "deepstack_object",
33
"name": "deepstack object custom integration",
44
"documentation": "https://github.com/robmarkcole/HASS-Deepstack-object",
5-
"version": "4.3.0",
5+
"version": "4.4.0",
66
"requirements": [
77
"pillow",
88
"deepstack-python==0.8"

0 commit comments

Comments
 (0)