Skip to content

Commit 2354055

Browse files
Adjust to results of internal pool regarding naming conventions
1 parent e97535a commit 2354055

File tree

35 files changed

+427
-84
lines changed

35 files changed

+427
-84
lines changed

docs/workflows/execution_engine_changelog.md

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,37 @@ Below you can find the changelog for Execution Engine.
44

55
## Execution Engine `v1.2.0` | inference `v0.23.0`
66

7-
* [`video_metadata` kind](/workflows/kinds/video_metadata/) got deprecated - **we advise not using this kind for
8-
building blocks from now on.** As an alternative approach, [`image` kind](/workflows/kinds/image/) internal and
9-
external representation got extended with the same metadata that
10-
[`video_metadata` kind](/workflows/kinds/video_metadata/) has, which can be provided optionally - making this
11-
change **non-breaking** for all old blocks, yet **making some old blocks producing images** incompatible with
12-
video processing blocks that will come in the future. Old blocks may also continue using
13-
[`video_metadata` kind](/workflows/kinds/video_metadata/), as it is left for now and will be removed in `v2.0.0`.
7+
* The [`video_metadata` kind](/workflows/kinds/video_metadata/) has been deprecated, and we **strongly recommend discontinuing its use for building
8+
blocks moving forward**. As an alternative, the [`image` kind](/workflows/kinds/image/) has been extended to support the same metadata as
9+
[`video_metadata` kind](/workflows/kinds/video_metadata/), which can now be provided optionally. This update is
10+
**non-breaking** for existing blocks, but **some older blocks** that produce images **may become incompatible** with
11+
**future** video processing blocks.
1412

1513
??? warning "Potential blocks incompatibility"
1614

17-
As it was mentioned, adding `video_metadata` to `image` kind as optional set of metadata may create a friction
18-
between already existing blocks that output `image` kind and future video processing blocks relying on
19-
`video_metadata` that will be created. The reason is the following - since we are able to provide
20-
default value for `video_metadata` in `image`, without explicitly copying them from the input image in the block,
21-
non-default metadata are lost and downstream blocks relying on the metadata may not work 100% as they should.
22-
We adjusted all existing `roboflow_core` blocks to follow, but all blocks created prior this change in external
23-
repositories may produce miss-behaviong Workflows when the output images are used by video-processing blocks.
15+
As previously mentioned, adding `video_metadata` as an optional field to the internal representation of
16+
[`image` kind](/workflows/kinds/image/) (`WorkflowImageData` class)
17+
may introduce some friction between existing blocks that output the [`image` kind](/workflows/kinds/image/) and
18+
future video processing blocks that rely on `video_metadata` being part of `image` representation.
19+
20+
The issue arises because, while we can provide **default** values for `video_metadata` in `image` without
21+
explicitly copying them from the input, any non-default metadata that was added upstream may be lost.
22+
This can lead to downstream blocks that depend on the `video_metadata` not functioning as expected.
2423

25-
* As a result of the above, [`image` kind](/workflows/kinds/image/) got updated internal representation - there is
26-
new property `video_metadata` which can be optionally set in constructor, if not - default value with reasonable
27-
defaults will be provided. Additionally, to make it easier to manipulate metadata in blocks, `update_image(...)` and
28-
`build_crop(...)` methods were added - see updates in
29-
[`WoorkflowImageData` usage guide](/workflows/internal_data_types/#workflowimagedata)
24+
We've updated all existing `roboflow_core` blocks to account for this, but blocks created before this change in
25+
external repositories may cause issues in workflows where their output images are used by video processing blocks.
3026

3127

32-
!!! warning "Breaking change planned - `v2.0.0`"
28+
* While the deprecated [`video_metadata` kind](/workflows/kinds/video_metadata/) is still available for use, it will be fully removed in
29+
Execution Engine version `v2.0.0`.
30+
31+
!!! warning "Breaking change planned - Execution Engine `v2.0.0`"
3332

3433
[`video_metadata` kind](/workflows/kinds/video_metadata/) got deprecated and will be removed in `v2.0.0`
3534

3635

37-
36+
* As a result of the changes mentioned above, the internal representation of the [`image` kind](/workflows/kinds/image/) has been updated to
37+
include a new `video_metadata` property. This property can be optionally set in the constructor; if not provided,
38+
a default value with reasonable defaults will be used. To simplify metadata manipulation within blocks, we have
39+
introduced two new class methods: `WorkflowImageData.copy_and_replace(...)` and `WorkflowImageData.create_crop(...)`.
40+
For more details, refer to the updated [`WoorkflowImageData` usage guide](/workflows/internal_data_types/#workflowimagedata).

docs/workflows/internal_data_types.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,11 @@ def transform_image(image: WorkflowImageData) -> WorkflowImageData:
157157
# data lineage (the predecessor-successor relation for images).
158158
# Lineage is not preserved for cropping and merging images (without common predecessor)
159159
# - below you may find implementation tips.
160-
return image.update_image(image=transformed_image)
160+
return WorkflowImageData.copy_and_replace(
161+
origin_image_data=image,
162+
numpy_image=transformed_image,
163+
)
164+
161165

162166
def some_transformation(image: np.ndarray) -> np.ndarray:
163167
...
@@ -188,7 +192,8 @@ def some_transformation(image: np.ndarray) -> np.ndarray:
188192
if not cropped_image.size:
189193
# discarding empty crops
190194
continue
191-
result_crop = image.build_crop(
195+
result_crop = WorkflowImageData.create_crop(
196+
origin_image_data=image,
192197
crop_identifier=crop_id,
193198
cropped_image=cropped_image,
194199
offset_x=x_min,
@@ -201,7 +206,7 @@ def some_transformation(image: np.ndarray) -> np.ndarray:
201206
In some cases you may want to preserve `video_metadata`. Example of such situation is when
202207
your block produces crops based on fixed coordinates (like video single footage with multiple fixed Regions of
203208
Interest to be applied individual trackers) - then you want result crops to be processed in context of video,
204-
as if they were produced by separate cameras. To adjust behaviour of `build_crop(...)` method, simply add
209+
as if they were produced by separate cameras. To adjust behaviour of `create_crop(...)` method, simply add
205210
`preserve_video_metadata=True`:
206211

207212
```{ .py linenums="1" hl_lines="11"}
@@ -210,7 +215,8 @@ def some_transformation(image: np.ndarray) -> np.ndarray:
210215
crops: List[Tuple[str, int, int, int, int]],
211216
) -> List[WorkflowImageData]:
212217
# [...]
213-
result_crop = image.build_crop(
218+
result_crop = WorkflowImageData.create_crop(
219+
origin_image_data=image,
214220
crop_identifier=crop_id,
215221
cropped_image=cropped_image,
216222
offset_x=x_min,

inference/core/workflows/core_steps/classical_cv/camera_focus/v1.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ def get_manifest(cls) -> Type[CameraFocusManifest]:
8383
def run(self, image: WorkflowImageData, *args, **kwargs) -> BlockResult:
8484
# Calculate the Brenner measure
8585
brenner_image, brenner_value = calculate_brenner_measure(image.numpy_image)
86-
output = image.update_image(image=brenner_image)
87-
86+
output = WorkflowImageData.copy_and_replace(
87+
origin_image_data=image,
88+
numpy_image=brenner_image,
89+
)
8890
return {
8991
OUTPUT_IMAGE_KEY: output,
9092
"focus_measure": brenner_value,

inference/core/workflows/core_steps/classical_cv/contours/v1.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ def run(
107107
contour_image, contours, hierarchy = find_and_draw_contours(
108108
image.numpy_image, thickness=line_thickness
109109
)
110-
111-
output = image.update_image(image=contour_image)
112-
110+
output = WorkflowImageData.copy_and_replace(
111+
origin_image_data=image, numpy_image=contour_image
112+
)
113113
return {
114114
OUTPUT_IMAGE_KEY: output,
115115
"contours": contours,

inference/core/workflows/core_steps/classical_cv/convert_grayscale/v1.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,7 @@ def run(
7979
) -> BlockResult:
8080
# Convert the image to grayscale
8181
gray = cv2.cvtColor(image.numpy_image, cv2.COLOR_BGR2GRAY)
82-
output = image.update_image(image=gray)
82+
output = WorkflowImageData.copy_and_replace(
83+
origin_image_data=image, numpy_image=gray
84+
)
8385
return {OUTPUT_IMAGE_KEY: output}

inference/core/workflows/core_steps/classical_cv/image_blur/v1.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ def run(
101101
) -> BlockResult:
102102
# Apply blur to the image
103103
blurred_image = apply_blur(image.numpy_image, blur_type, kernel_size)
104-
output = image.update_image(image=blurred_image)
104+
output = WorkflowImageData.copy_and_replace(
105+
origin_image_data=image,
106+
numpy_image=blurred_image,
107+
)
105108
return {OUTPUT_IMAGE_KEY: output}
106109

107110

inference/core/workflows/core_steps/classical_cv/image_preprocessing/v1.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ def run(
160160
else:
161161
raise ValueError(f"Invalid task type: {task_type}")
162162

163-
output_image = image.update_image(image=response_image)
163+
output_image = WorkflowImageData.copy_and_replace(
164+
origin_image_data=image, numpy_image=response_image
165+
)
164166
return {"image": output_image}
165167

166168

inference/core/workflows/core_steps/classical_cv/sift/v1.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ def get_manifest(cls) -> Type[SIFTDetectionManifest]:
8787

8888
def run(self, image: WorkflowImageData, *args, **kwargs) -> BlockResult:
8989
img_with_kp, keypoints, descriptors = apply_sift(image.numpy_image)
90-
output_image = image.update_image(image=img_with_kp)
90+
output_image = WorkflowImageData.copy_and_replace(
91+
origin_image_data=image,
92+
numpy_image=img_with_kp,
93+
)
9194
return {
9295
OUTPUT_IMAGE_KEY: output_image,
9396
"keypoints": keypoints,

inference/core/workflows/core_steps/classical_cv/sift_comparison/v2.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,16 @@ def run(
201201
images_match = good_matches_count >= good_matches_threshold
202202

203203
if visualization_1 is not None:
204-
visualization_1 = input_1.update_image(image=visualization_1)
204+
visualization_1 = WorkflowImageData.copy_and_replace(
205+
origin_image_data=input_1,
206+
numpy_image=visualization_1,
207+
)
205208

206209
if visualization_2 is not None:
207-
visualization_2 = input_2.update_image(image=visualization_2)
210+
visualization_2 = WorkflowImageData.copy_and_replace(
211+
origin_image_data=input_2,
212+
numpy_image=visualization_2,
213+
)
208214

209215
visualization_matches = None
210216
if visualize and image_1 is not None and image_2 is not None:
@@ -229,7 +235,10 @@ def run(
229235
**draw_params,
230236
)
231237

232-
visualization_matches = input_1.update_image(image=visualization_matches)
238+
visualization_matches = WorkflowImageData.copy_and_replace(
239+
origin_image_data=input_1,
240+
numpy_image=visualization_matches,
241+
)
233242

234243
return {
235244
"good_matches_count": good_matches_count,

inference/core/workflows/core_steps/classical_cv/threshold/v1.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ def run(
117117
thresholded_image = apply_thresholding(
118118
image.numpy_image, threshold_type, thresh_value, max_value
119119
)
120-
output = image.update_image(image=thresholded_image)
120+
output = WorkflowImageData.copy_and_replace(
121+
origin_image_data=image,
122+
numpy_image=thresholded_image,
123+
)
121124
return {OUTPUT_IMAGE_KEY: output}
122125

123126

0 commit comments

Comments
 (0)