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 all 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_to_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_to_roi**: (optional, default False), crops the image to the specified roi. May improve object detection accuracy when a region-of-interest is applied
- **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_to_roi"

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.4.0",
"requirements": [
"pillow",
"deepstack-python==0.8"
Expand Down