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

add crop_roi option #271

Merged
merged 3 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ image_processing:
roi_x_max: 0.8
#roi_y_min: 0.4
roi_y_max: 0.8
crop_roi: True
targets:
- target: person
- target: vehicle
Expand Down Expand Up @@ -64,6 +65,7 @@ Configuration variables:
- **roi_x_max**: (optional, default 1), range 0-1, must be more than roi_x_min
- **roi_y_min**: (optional, default 0), range 0-1, must be less than roi_y_max
- **roi_y_max**: (optional, default 1), range 0-1, must be more than roi_y_min
- **crop_roi**: (oprional, default False), crops the image to the specified roi. This reduces disk space used, and improves performance (speed and object detection) when regions-of-interest are applied.
wizmo2 marked this conversation as resolved.
Show resolved Hide resolved
wizmo2 marked this conversation as resolved.
Show resolved Hide resolved
- **source**: Must be a camera.
- **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%.

Expand Down
28 changes: 25 additions & 3 deletions custom_components/deepstack_object/image_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
CONF_ROI_X_MAX = "roi_x_max"
CONF_SCALE = "scale"
CONF_CUSTOM_MODEL = "custom_model"
CONF_CROP_ROI = "crop_roi"
wizmo2 marked this conversation as resolved.
Show resolved Hide resolved

DATETIME_FORMAT = "%Y-%m-%d_%H-%M-%S-%f"
DEFAULT_API_KEY = ""
Expand Down Expand Up @@ -138,6 +139,7 @@
vol.Optional(CONF_SAVE_TIMESTAMPTED_FILE, default=False): cv.boolean,
vol.Optional(CONF_ALWAYS_SAVE_LATEST_FILE, default=False): cv.boolean,
vol.Optional(CONF_SHOW_BOXES, default=True): cv.boolean,
vol.Optional(CONF_CROP_ROI, default=False): cv.boolean,
}
)

Expand Down Expand Up @@ -237,6 +239,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
save_file_format=config[CONF_SAVE_FILE_FORMAT],
save_timestamped_file=config.get(CONF_SAVE_TIMESTAMPTED_FILE),
always_save_latest_file=config.get(CONF_ALWAYS_SAVE_LATEST_FILE),
crop_roi=config[CONF_CROP_ROI],
camera_entity=camera.get(CONF_ENTITY_ID),
name=camera.get(CONF_NAME),
)
Expand Down Expand Up @@ -266,6 +269,7 @@ def __init__(
save_file_format,
save_timestamped_file,
always_save_latest_file,
crop_roi,
camera_entity,
name=None,
):
Expand Down Expand Up @@ -307,6 +311,7 @@ def __init__(
"y_max": roi_y_max,
"x_max": roi_x_max,
}
self._crop_roi = crop_roi
self._scale = scale
self._show_boxes = show_boxes
self._image_width = None
Expand All @@ -322,7 +327,24 @@ def process_image(self, image):
"""Process an image."""
self._image = Image.open(io.BytesIO(bytearray(image)))
self._image_width, self._image_height = self._image.size

# scale to roi
if self._crop_roi:
roi = (
self._image_width * self._roi_dict["x_min"],
self._image_height * self._roi_dict["y_min"],
self._image_width * (self._roi_dict["x_max"]),
self._image_height * (self._roi_dict["y_max"])
)
self._image = self._image.crop(roi)
self._image_width, self._image_height = self._image.size
with io.BytesIO() as output:
self._image.save(output, format="JPEG")
image = output.getvalue()
_LOGGER.debug(
(
f"Image cropped with : {self._roi_dict} W={self._image_width} H={self._image_height}"
)
)
# resize image if different then default
if self._scale != DEAULT_SCALE:
newsize = (self._image_width * self._scale, self._image_width * self._scale)
Expand Down Expand Up @@ -368,7 +390,7 @@ def process_image(self, image):
if obj["name"] == target[CONF_TARGET]:
confidence = target[CONF_CONFIDENCE]
if obj["confidence"] > confidence:
if not object_in_roi(self._roi_dict, obj["centroid"]):
if not self._crop_roi and not object_in_roi(self._roi_dict, obj["centroid"]):
continue
self._targets_found.append(obj)

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

roi_tuple = tuple(self._roi_dict.values())
if roi_tuple != DEFAULT_ROI and self._show_boxes:
if roi_tuple != DEFAULT_ROI and self._show_boxes and not self._crop_roi:
draw_box(
draw,
roi_tuple,
Expand Down
2 changes: 1 addition & 1 deletion custom_components/deepstack_object/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"domain": "deepstack_object",
"name": "deepstack object custom integration",
"documentation": "https://github.com/robmarkcole/HASS-Deepstack-object",
"version": "4.3.0",
"version": "4.3.1",
wizmo2 marked this conversation as resolved.
Show resolved Hide resolved
"requirements": [
"pillow",
"deepstack-python==0.8"
Expand Down