50
50
51
51
* **"vertical_bottom_to_top"**: Vertical reading from bottom to top ⬆️
52
52
53
+ * **"auto"**: Automatically detects the reading direction based on the spatial arrangement of text elements.
54
+
53
55
#### Why Use This Transformation?
54
56
55
57
This is especially useful for:
@@ -109,6 +111,7 @@ class BlockManifest(WorkflowBlockManifest):
109
111
"right_to_left",
110
112
"vertical_top_to_bottom",
111
113
"vertical_bottom_to_top",
114
+ "auto",
112
115
] = Field(
113
116
title="Reading Direction",
114
117
description="The direction of the text in the image.",
@@ -131,6 +134,10 @@ class BlockManifest(WorkflowBlockManifest):
131
134
"name": "Bottom To Top (Vertical)",
132
135
"description": "Vertical reading from bottom to top",
133
136
},
137
+ "auto": {
138
+ "name": "Auto",
139
+ "description": "Automatically detect the reading direction based on text arrangement.",
140
+ },
134
141
}
135
142
},
136
143
)
@@ -167,6 +174,23 @@ def get_execution_engine_compatibility(cls) -> Optional[str]:
167
174
return ">=1.0.0,<2.0.0"
168
175
169
176
177
+ def detect_reading_direction(detections: sv.Detections) -> str:
178
+ if len(detections) == 0:
179
+ return "left_to_right"
180
+
181
+ xyxy = detections.xyxy
182
+ widths = xyxy[:, 2] - xyxy[:, 0]
183
+ heights = xyxy[:, 3] - xyxy[:, 1]
184
+
185
+ avg_width = np.mean(widths)
186
+ avg_height = np.mean(heights)
187
+
188
+ if avg_width > avg_height:
189
+ return "left_to_right"
190
+ else:
191
+ return "vertical_top_to_bottom"
192
+
193
+
170
194
class StitchOCRDetectionsBlockV1(WorkflowBlock):
171
195
@classmethod
172
196
def get_manifest(cls) -> Type[WorkflowBlockManifest]:
@@ -178,6 +202,8 @@ def run(
178
202
reading_direction: str,
179
203
tolerance: int,
180
204
) -> BlockResult:
205
+ if reading_direction == "auto":
206
+ reading_direction = detect_reading_direction(predictions[0])
181
207
return [
182
208
stitch_ocr_detections(
183
209
detections=detections,
0 commit comments