valetudo-map-parser 0.1.9b5__py3-none-any.whl → 0.1.9b7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- valetudo_map_parser/config/utils.py +324 -8
- valetudo_map_parser/hypfer_draw.py +1 -1
- valetudo_map_parser/hypfer_handler.py +4 -6
- valetudo_map_parser/rand25_handler.py +3 -5
- valetudo_map_parser/reimg_draw.py +0 -2
- {valetudo_map_parser-0.1.9b5.dist-info → valetudo_map_parser-0.1.9b7.dist-info}/METADATA +1 -1
- {valetudo_map_parser-0.1.9b5.dist-info → valetudo_map_parser-0.1.9b7.dist-info}/RECORD +10 -11
- valetudo_map_parser/images_utils.py +0 -335
- {valetudo_map_parser-0.1.9b5.dist-info → valetudo_map_parser-0.1.9b7.dist-info}/LICENSE +0 -0
- {valetudo_map_parser-0.1.9b5.dist-info → valetudo_map_parser-0.1.9b7.dist-info}/NOTICE.txt +0 -0
- {valetudo_map_parser-0.1.9b5.dist-info → valetudo_map_parser-0.1.9b7.dist-info}/WHEEL +0 -0
@@ -6,7 +6,6 @@ from logging import getLogger
|
|
6
6
|
|
7
7
|
from PIL import ImageOps
|
8
8
|
|
9
|
-
from ..images_utils import ImageUtils as ImUtils
|
10
9
|
from .types import ChargerPosition, ImageSize, NumpyArray, RobotPosition
|
11
10
|
|
12
11
|
_LOGGER = getLogger(__name__)
|
@@ -29,7 +28,9 @@ class BaseHandler:
|
|
29
28
|
self.frame_number = 0
|
30
29
|
self.max_frames = 1024
|
31
30
|
self.crop_img_size = [0, 0]
|
32
|
-
self.
|
31
|
+
self.offset_x = 0
|
32
|
+
self.offset_y = 0
|
33
|
+
self.shared = None
|
33
34
|
|
34
35
|
def get_frame_number(self) -> int:
|
35
36
|
"""Return the frame number of the image."""
|
@@ -89,17 +90,17 @@ class BaseHandler:
|
|
89
90
|
"""
|
90
91
|
|
91
92
|
if wsf == 1 and hsf == 1:
|
92
|
-
self.
|
93
|
+
self.set_image_offset_ratio_1_1(width, height, rand256)
|
93
94
|
elif wsf == 2 and hsf == 1:
|
94
|
-
self.
|
95
|
+
self.set_image_offset_ratio_2_1(width, height, rand256)
|
95
96
|
elif wsf == 3 and hsf == 2:
|
96
|
-
self.
|
97
|
+
self.set_image_offset_ratio_3_2(width, height, rand256)
|
97
98
|
elif wsf == 5 and hsf == 4:
|
98
|
-
self.
|
99
|
+
self.set_image_offset_ratio_5_4(width, height, rand256)
|
99
100
|
elif wsf == 9 and hsf == 16:
|
100
|
-
self.
|
101
|
+
self.set_image_offset_ratio_9_16(width, height, rand256)
|
101
102
|
elif wsf == 16 and hsf == 9:
|
102
|
-
self.
|
103
|
+
self.set_image_offset_ratio_16_9(width, height, rand256)
|
103
104
|
return width, height
|
104
105
|
|
105
106
|
@staticmethod
|
@@ -130,3 +131,318 @@ class BaseHandler:
|
|
130
131
|
}, # Bottom-right corner 2
|
131
132
|
{"x": 0, "y": self.crop_img_size[1]}, # Bottom-left corner (optional) 3
|
132
133
|
]
|
134
|
+
|
135
|
+
def set_image_offset_ratio_1_1(
|
136
|
+
self, width: int, height: int, rand256: bool = False
|
137
|
+
) -> None:
|
138
|
+
"""Set the image offset ratio to 1:1."""
|
139
|
+
|
140
|
+
rotation = self.shared.image_rotate
|
141
|
+
if not rand256:
|
142
|
+
if rotation in [0, 180]:
|
143
|
+
self.offset_y = self.crop_img_size[0] - width
|
144
|
+
self.offset_x = (height - self.crop_img_size[1]) // 2
|
145
|
+
elif rotation in [90, 270]:
|
146
|
+
self.offset_y = width - self.crop_img_size[0]
|
147
|
+
self.offset_x = (self.crop_img_size[1] - height) // 2
|
148
|
+
else:
|
149
|
+
if rotation in [0, 180]:
|
150
|
+
self.offset_x = (width - self.crop_img_size[0]) // 2
|
151
|
+
self.offset_y = height - self.crop_img_size[1]
|
152
|
+
elif rotation in [90, 270]:
|
153
|
+
self.offset_y = (self.crop_img_size[0] - width) // 2
|
154
|
+
self.offset_x = self.crop_img_size[1] - height
|
155
|
+
_LOGGER.debug(
|
156
|
+
"%s Image Coordinates Offsets (x,y): %s. %s",
|
157
|
+
self.file_name,
|
158
|
+
self.offset_x,
|
159
|
+
self.offset_y,
|
160
|
+
)
|
161
|
+
|
162
|
+
def set_image_offset_ratio_2_1(
|
163
|
+
self, width: int, height: int, rand256: bool = False
|
164
|
+
) -> None:
|
165
|
+
"""Set the image offset ratio to 2:1."""
|
166
|
+
|
167
|
+
rotation = self.shared.image_rotate
|
168
|
+
if not rand256:
|
169
|
+
if rotation in [0, 180]:
|
170
|
+
self.offset_y = width - self.crop_img_size[0]
|
171
|
+
self.offset_x = height - self.crop_img_size[1]
|
172
|
+
elif rotation in [90, 270]:
|
173
|
+
self.offset_x = width - self.crop_img_size[0]
|
174
|
+
self.offset_y = height - self.crop_img_size[1]
|
175
|
+
else:
|
176
|
+
if rotation in [0, 180]:
|
177
|
+
self.offset_y = width - self.crop_img_size[0]
|
178
|
+
self.offset_x = height - self.crop_img_size[1]
|
179
|
+
elif rotation in [90, 270]:
|
180
|
+
self.offset_x = width - self.crop_img_size[0]
|
181
|
+
self.offset_y = height - self.crop_img_size[1]
|
182
|
+
|
183
|
+
_LOGGER.debug(
|
184
|
+
"%s Image Coordinates Offsets (x,y): %s. %s",
|
185
|
+
self.file_name,
|
186
|
+
self.offset_x,
|
187
|
+
self.offset_y,
|
188
|
+
)
|
189
|
+
|
190
|
+
def set_image_offset_ratio_3_2(
|
191
|
+
self, width: int, height: int, rand256: bool = False
|
192
|
+
) -> None:
|
193
|
+
"""Set the image offset ratio to 3:2."""
|
194
|
+
|
195
|
+
rotation = self.shared.image_rotate
|
196
|
+
|
197
|
+
if not rand256:
|
198
|
+
if rotation in [0, 180]:
|
199
|
+
self.offset_y = width - self.crop_img_size[0]
|
200
|
+
self.offset_x = ((height - self.crop_img_size[1]) // 2) - (
|
201
|
+
self.crop_img_size[1] // 10
|
202
|
+
)
|
203
|
+
elif rotation in [90, 270]:
|
204
|
+
self.offset_y = (self.crop_img_size[0] - width) // 2
|
205
|
+
self.offset_x = (self.crop_img_size[1] - height) + (
|
206
|
+
(height // 10) // 2
|
207
|
+
)
|
208
|
+
else:
|
209
|
+
if rotation in [0, 180]:
|
210
|
+
self.offset_x = (width - self.crop_img_size[0]) // 2
|
211
|
+
self.offset_y = height - self.crop_img_size[1]
|
212
|
+
elif rotation in [90, 270]:
|
213
|
+
self.offset_y = (self.crop_img_size[0] - width) // 2
|
214
|
+
self.offset_x = self.crop_img_size[1] - height
|
215
|
+
|
216
|
+
_LOGGER.debug(
|
217
|
+
"%s Image Coordinates Offsets (x,y): %s. %s",
|
218
|
+
self.file_name,
|
219
|
+
self.offset_x,
|
220
|
+
self.offset_y,
|
221
|
+
)
|
222
|
+
|
223
|
+
def set_image_offset_ratio_5_4(
|
224
|
+
self, width: int, height: int, rand256: bool = False
|
225
|
+
) -> None:
|
226
|
+
"""Set the image offset ratio to 5:4."""
|
227
|
+
|
228
|
+
rotation = self.shared.image_rotate
|
229
|
+
if not rand256:
|
230
|
+
if rotation in [0, 180]:
|
231
|
+
self.offset_x = ((width - self.crop_img_size[0]) // 2) - (
|
232
|
+
self.crop_img_size[0] // 2
|
233
|
+
)
|
234
|
+
self.offset_y = (self.crop_img_size[1] - height) - (
|
235
|
+
self.crop_img_size[1] // 2
|
236
|
+
)
|
237
|
+
elif rotation in [90, 270]:
|
238
|
+
self.offset_y = ((self.crop_img_size[0] - width) // 2) - 10
|
239
|
+
self.offset_x = (self.crop_img_size[1] - height) + (
|
240
|
+
height // 10
|
241
|
+
)
|
242
|
+
else:
|
243
|
+
if rotation in [0, 180]:
|
244
|
+
self.offset_y = (width - self.crop_img_size[0]) // 2
|
245
|
+
self.offset_x = self.crop_img_size[1] - height
|
246
|
+
elif rotation in [90, 270]:
|
247
|
+
self.offset_y = (self.crop_img_size[0] - width) // 2
|
248
|
+
self.offset_x = self.crop_img_size[1] - height
|
249
|
+
|
250
|
+
_LOGGER.debug(
|
251
|
+
"%s Image Coordinates Offsets (x,y): %s. %s",
|
252
|
+
self.file_name,
|
253
|
+
self.offset_x,
|
254
|
+
self.offset_y,
|
255
|
+
)
|
256
|
+
|
257
|
+
def set_image_offset_ratio_9_16(
|
258
|
+
self, width: int, height: int, rand256: bool = False
|
259
|
+
) -> None:
|
260
|
+
"""Set the image offset ratio to 9:16."""
|
261
|
+
|
262
|
+
rotation = self.shared.image_rotate
|
263
|
+
if not rand256:
|
264
|
+
if rotation in [0, 180]:
|
265
|
+
self.offset_y = width - self.crop_img_size[0]
|
266
|
+
self.offset_x = height - self.crop_img_size[1]
|
267
|
+
elif rotation in [90, 270]:
|
268
|
+
self.offset_x = (width - self.crop_img_size[0]) + (height // 10)
|
269
|
+
self.offset_y = height - self.crop_img_size[1]
|
270
|
+
else:
|
271
|
+
if rotation in [0, 180]:
|
272
|
+
self.offset_y = width - self.crop_img_size[0]
|
273
|
+
self.offset_x = height - self.crop_img_size[1]
|
274
|
+
elif rotation in [90, 270]:
|
275
|
+
self.offset_x = width - self.crop_img_size[0]
|
276
|
+
self.offset_y = height - self.crop_img_size[1]
|
277
|
+
|
278
|
+
_LOGGER.debug(
|
279
|
+
"%s Image Coordinates Offsets (x,y): %s. %s",
|
280
|
+
self.file_name,
|
281
|
+
self.offset_x,
|
282
|
+
self.offset_y,
|
283
|
+
)
|
284
|
+
|
285
|
+
def set_image_offset_ratio_16_9(
|
286
|
+
self, width: int, height: int, rand256: bool = False
|
287
|
+
) -> None:
|
288
|
+
"""Set the image offset ratio to 16:9."""
|
289
|
+
|
290
|
+
rotation = self.shared.image_rotate
|
291
|
+
if not rand256:
|
292
|
+
if rotation in [0, 180]:
|
293
|
+
self.offset_y = width - self.crop_img_size[0]
|
294
|
+
self.offset_x = height - self.crop_img_size[1]
|
295
|
+
elif rotation in [90, 270]:
|
296
|
+
self.offset_x = width - self.crop_img_size[0]
|
297
|
+
self.offset_y = height - self.crop_img_size[1]
|
298
|
+
else:
|
299
|
+
if rotation in [0, 180]:
|
300
|
+
self.offset_y = width - self.crop_img_size[0]
|
301
|
+
self.offset_x = height - self.crop_img_size[1]
|
302
|
+
elif rotation in [90, 270]:
|
303
|
+
self.offset_x = width - self.crop_img_size[0]
|
304
|
+
self.offset_y = height - self.crop_img_size[1]
|
305
|
+
|
306
|
+
_LOGGER.debug(
|
307
|
+
"%s Image Coordinates Offsets (x,y): %s. %s",
|
308
|
+
self.file_name,
|
309
|
+
self.offset_x,
|
310
|
+
self.offset_y,
|
311
|
+
)
|
312
|
+
|
313
|
+
def get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
|
314
|
+
"""Calculate the calibration points based on the rotation angle."""
|
315
|
+
|
316
|
+
# get_calibration_data
|
317
|
+
vacuum_points = [
|
318
|
+
{
|
319
|
+
"x": self.img.crop_area[0] + self.img.offset_x,
|
320
|
+
"y": self.img.crop_area[1] + self.img.offset_y,
|
321
|
+
}, # Top-left corner 0
|
322
|
+
{
|
323
|
+
"x": self.img.crop_area[2] - self.img.offset_x,
|
324
|
+
"y": self.img.crop_area[1] + self.img.offset_y,
|
325
|
+
}, # Top-right corner 1
|
326
|
+
{
|
327
|
+
"x": self.img.crop_area[2] - self.img.offset_x,
|
328
|
+
"y": self.img.crop_area[3] - self.img.offset_y,
|
329
|
+
}, # Bottom-right corner 2
|
330
|
+
{
|
331
|
+
"x": self.img.crop_area[0] + self.img.offset_x,
|
332
|
+
"y": self.img.crop_area[3] - self.img.offset_y,
|
333
|
+
}, # Bottom-left corner (optional)3
|
334
|
+
]
|
335
|
+
|
336
|
+
# Rotate the vacuum points based on the rotation angle
|
337
|
+
if rotation_angle == 90:
|
338
|
+
vacuum_points = [
|
339
|
+
vacuum_points[1],
|
340
|
+
vacuum_points[2],
|
341
|
+
vacuum_points[3],
|
342
|
+
vacuum_points[0],
|
343
|
+
]
|
344
|
+
elif rotation_angle == 180:
|
345
|
+
vacuum_points = [
|
346
|
+
vacuum_points[2],
|
347
|
+
vacuum_points[3],
|
348
|
+
vacuum_points[0],
|
349
|
+
vacuum_points[1],
|
350
|
+
]
|
351
|
+
elif rotation_angle == 270:
|
352
|
+
vacuum_points = [
|
353
|
+
vacuum_points[3],
|
354
|
+
vacuum_points[0],
|
355
|
+
vacuum_points[1],
|
356
|
+
vacuum_points[2],
|
357
|
+
]
|
358
|
+
|
359
|
+
return vacuum_points
|
360
|
+
|
361
|
+
def re_get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
|
362
|
+
"""Recalculate the calibration points based on the rotation angle.
|
363
|
+
RAND256 Vacuums Calibration Points are in 10th of a mm."""
|
364
|
+
vacuum_points = [
|
365
|
+
{
|
366
|
+
"x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
|
367
|
+
"y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
|
368
|
+
}, # Top-left corner 0
|
369
|
+
{
|
370
|
+
"x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
|
371
|
+
"y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
|
372
|
+
}, # Top-right corner 1
|
373
|
+
{
|
374
|
+
"x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
|
375
|
+
"y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
|
376
|
+
}, # Bottom-right corner 2
|
377
|
+
{
|
378
|
+
"x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
|
379
|
+
"y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
|
380
|
+
}, # Bottom-left corner (optional)3
|
381
|
+
]
|
382
|
+
|
383
|
+
# Rotate the vacuum points based on the rotation angle
|
384
|
+
if rotation_angle == 90:
|
385
|
+
vacuum_points = [
|
386
|
+
vacuum_points[1],
|
387
|
+
vacuum_points[2],
|
388
|
+
vacuum_points[3],
|
389
|
+
vacuum_points[0],
|
390
|
+
]
|
391
|
+
elif rotation_angle == 180:
|
392
|
+
vacuum_points = [
|
393
|
+
vacuum_points[2],
|
394
|
+
vacuum_points[3],
|
395
|
+
vacuum_points[0],
|
396
|
+
vacuum_points[1],
|
397
|
+
]
|
398
|
+
elif rotation_angle == 270:
|
399
|
+
vacuum_points = [
|
400
|
+
vacuum_points[3],
|
401
|
+
vacuum_points[0],
|
402
|
+
vacuum_points[1],
|
403
|
+
vacuum_points[2],
|
404
|
+
]
|
405
|
+
|
406
|
+
return vacuum_points
|
407
|
+
|
408
|
+
async def async_zone_propriety(self, zones_data) -> dict:
|
409
|
+
"""Get the zone propriety"""
|
410
|
+
zone_properties = {}
|
411
|
+
id_count = 1
|
412
|
+
for zone in zones_data:
|
413
|
+
zone_name = zone.get("name")
|
414
|
+
coordinates = zone.get("coordinates")
|
415
|
+
if coordinates and len(coordinates) > 0:
|
416
|
+
coordinates[0].pop()
|
417
|
+
x1, y1, x2, y2 = coordinates[0]
|
418
|
+
zone_properties[zone_name] = {
|
419
|
+
"zones": coordinates,
|
420
|
+
"name": zone_name,
|
421
|
+
"x": ((x1 + x2) // 2),
|
422
|
+
"y": ((y1 + y2) // 2),
|
423
|
+
}
|
424
|
+
id_count += 1
|
425
|
+
if id_count > 1:
|
426
|
+
_LOGGER.debug("%s: Zones Properties updated.", self.file_name)
|
427
|
+
return zone_properties
|
428
|
+
|
429
|
+
async def async_points_propriety(self, points_data) -> dict:
|
430
|
+
"""Get the point propriety"""
|
431
|
+
point_properties = {}
|
432
|
+
id_count = 1
|
433
|
+
for point in points_data:
|
434
|
+
point_name = point.get("name")
|
435
|
+
coordinates = point.get("coordinates")
|
436
|
+
if coordinates and len(coordinates) > 0:
|
437
|
+
coordinates = point.get("coordinates")
|
438
|
+
x1, y1 = coordinates
|
439
|
+
point_properties[id_count] = {
|
440
|
+
"position": coordinates,
|
441
|
+
"name": point_name,
|
442
|
+
"x": x1,
|
443
|
+
"y": y1,
|
444
|
+
}
|
445
|
+
id_count += 1
|
446
|
+
if id_count > 1:
|
447
|
+
_LOGGER.debug("%s: Point Properties updated.", self.file_name)
|
448
|
+
return point_properties
|
@@ -70,7 +70,7 @@ class ImageDraw:
|
|
70
70
|
self, img_np_array, pixels, layer_type, room_id, pixel_size, color_zone_clean
|
71
71
|
):
|
72
72
|
"""Process a room layer (segment or floor)."""
|
73
|
-
room_color = self.img_h.rooms_colors[room_id]
|
73
|
+
room_color = self.img_h.shared.rooms_colors[room_id]
|
74
74
|
|
75
75
|
try:
|
76
76
|
if layer_type == "segment":
|
@@ -51,8 +51,6 @@ class HypferMapImageHandler(BaseHandler):
|
|
51
51
|
self.offset_bottom = self.shared.offset_down # offset bottom
|
52
52
|
self.offset_left = self.shared.offset_left # offset left
|
53
53
|
self.offset_right = self.shared.offset_right # offset right
|
54
|
-
self.offset_x = 0 # offset x for the aspect ratio.
|
55
|
-
self.offset_y = 0 # offset y for the aspect ratio.
|
56
54
|
self.imd = ImDraw(self)
|
57
55
|
self.ac = AutoCrop(self)
|
58
56
|
self.color_grey = (128, 128, 128, 255)
|
@@ -221,7 +219,7 @@ class HypferMapImageHandler(BaseHandler):
|
|
221
219
|
)
|
222
220
|
# Draw path prediction and paths.
|
223
221
|
img_np_array = await self.imd.async_draw_paths(
|
224
|
-
img_np_array, m_json, colors["
|
222
|
+
img_np_array, m_json, colors["move"], self.color_grey
|
225
223
|
)
|
226
224
|
# Check if the robot is docked.
|
227
225
|
if self.shared.vacuum_state == "docked":
|
@@ -235,13 +233,13 @@ class HypferMapImageHandler(BaseHandler):
|
|
235
233
|
x=robot_position[0],
|
236
234
|
y=robot_position[1],
|
237
235
|
angle=robot_position_angle,
|
238
|
-
fill=colors["
|
236
|
+
fill=colors["robot"],
|
239
237
|
robot_state=self.shared.vacuum_state,
|
240
238
|
)
|
241
239
|
# Resize the image
|
242
240
|
img_np_array = await self.ac.async_auto_trim_and_zoom_image(
|
243
241
|
img_np_array,
|
244
|
-
colors["
|
242
|
+
colors["background"],
|
245
243
|
int(self.shared.margins),
|
246
244
|
int(self.shared.image_rotate),
|
247
245
|
self.zooming,
|
@@ -303,7 +301,7 @@ class HypferMapImageHandler(BaseHandler):
|
|
303
301
|
# Define the map points (fixed)
|
304
302
|
map_points = self.get_map_points()
|
305
303
|
# Calculate the calibration points in the vacuum coordinate system
|
306
|
-
vacuum_points = self.
|
304
|
+
vacuum_points = self.get_vacuum_points(rotation_angle)
|
307
305
|
|
308
306
|
# Create the calibration data for each point
|
309
307
|
for vacuum_point, map_point in zip(vacuum_points, map_points):
|
@@ -57,8 +57,6 @@ class ReImageHandler(BaseHandler):
|
|
57
57
|
self.trim_up = None # Trim up
|
58
58
|
self.zooming = False # Zooming flag
|
59
59
|
self.file_name = self.shared.file_name # File name
|
60
|
-
self.offset_x = 0 # offset x for the aspect ratio.
|
61
|
-
self.offset_y = 0 # offset y for the aspect ratio.
|
62
60
|
self.offset_top = self.shared.offset_top # offset top
|
63
61
|
self.offset_bottom = self.shared.offset_down # offset bottom
|
64
62
|
self.offset_left = self.shared.offset_left # offset left
|
@@ -121,9 +119,9 @@ class ReImageHandler(BaseHandler):
|
|
121
119
|
"y": (y_min + y_max) // 2,
|
122
120
|
}
|
123
121
|
# get the zones and points data
|
124
|
-
zone_properties = await self.
|
122
|
+
zone_properties = await self.async_zone_propriety(zones_data)
|
125
123
|
# get the points data
|
126
|
-
point_properties = await self.
|
124
|
+
point_properties = await self.async_points_propriety(points_data)
|
127
125
|
if room_properties or zone_properties:
|
128
126
|
extracted_data = [
|
129
127
|
f"{len(room_properties)} Rooms" if room_properties else None,
|
@@ -381,7 +379,7 @@ class ReImageHandler(BaseHandler):
|
|
381
379
|
map_points = self.get_map_points()
|
382
380
|
|
383
381
|
# Valetudo Re version need corrections of the coordinates and are implemented with *10
|
384
|
-
vacuum_points = self.
|
382
|
+
vacuum_points = self.re_get_vacuum_points(rotation_angle)
|
385
383
|
|
386
384
|
# Create the calibration data for each point
|
387
385
|
for vacuum_point, map_point in zip(vacuum_points, map_points):
|
@@ -6,16 +6,15 @@ valetudo_map_parser/config/drawable.py,sha256=hsrEJCMVOrjs5sJfr26SeqJD0VNlYWwxcV
|
|
6
6
|
valetudo_map_parser/config/rand25_parser.py,sha256=fehyF18hRWRWbXbojocQCIaIch21Lbh1wtl2XdKRSl0,16447
|
7
7
|
valetudo_map_parser/config/shared.py,sha256=LQV5K8tbVhEKUkby9ssjEmh_T4Ai-Euzsbag_HWYVRc,9448
|
8
8
|
valetudo_map_parser/config/types.py,sha256=-8F1WwCH5hKSih83-WPjYbGdQyKmNqkDmSKvlyz6qPg,16163
|
9
|
-
valetudo_map_parser/config/utils.py,sha256=
|
10
|
-
valetudo_map_parser/hypfer_draw.py,sha256=
|
11
|
-
valetudo_map_parser/hypfer_handler.py,sha256=
|
12
|
-
valetudo_map_parser/images_utils.py,sha256=1HMf57CODrgfIsIxKAmHcfiylitQ-wUPEsYoqiGqHbo,12947
|
9
|
+
valetudo_map_parser/config/utils.py,sha256=W4meKptsRCAmfNLGPktFy1GiBM1F6tLLZW750VCwCJ8,16717
|
10
|
+
valetudo_map_parser/hypfer_draw.py,sha256=46bYtbcaZHDYDtOie4byM3Z8CcXw-vl7uQfwN7KdZOk,14958
|
11
|
+
valetudo_map_parser/hypfer_handler.py,sha256=u1-2AIjZyhKw0QvRT604Ns9NX7ARaACxwaiyktdOprQ,14069
|
13
12
|
valetudo_map_parser/map_data.py,sha256=qm1Zlfex0JrfhQsAKUOzsceZL0X92oAyGJ5Wvsq6YhA,19447
|
14
13
|
valetudo_map_parser/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
valetudo_map_parser/rand25_handler.py,sha256=
|
16
|
-
valetudo_map_parser/reimg_draw.py,sha256=
|
17
|
-
valetudo_map_parser-0.1.
|
18
|
-
valetudo_map_parser-0.1.
|
19
|
-
valetudo_map_parser-0.1.
|
20
|
-
valetudo_map_parser-0.1.
|
21
|
-
valetudo_map_parser-0.1.
|
14
|
+
valetudo_map_parser/rand25_handler.py,sha256=vph1BCO0g77kTi18y6sqqJfyJfT5033l9CoxJIDO1Ak,15827
|
15
|
+
valetudo_map_parser/reimg_draw.py,sha256=dtdbYKKxmQnbOaHBHayWEF07OdSnTKo2CPSOW0qpgH0,12506
|
16
|
+
valetudo_map_parser-0.1.9b7.dist-info/LICENSE,sha256=Lh-qBbuRV0-jiCIBhfV7NgdwFxQFOXH3BKOzK865hRs,10480
|
17
|
+
valetudo_map_parser-0.1.9b7.dist-info/METADATA,sha256=hIplZAuQgbccfthgYE_z_6MLvTPhiR_4y8XOkcT3Hqg,1028
|
18
|
+
valetudo_map_parser-0.1.9b7.dist-info/NOTICE.txt,sha256=5lTOuWiU9aiEnJ2go8sc7lTJ7ntMBx0g0GFnNrswCY4,2533
|
19
|
+
valetudo_map_parser-0.1.9b7.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
20
|
+
valetudo_map_parser-0.1.9b7.dist-info/RECORD,,
|
@@ -1,335 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Image Utils Class for Valetudo Hypfer Image Handling.
|
3
|
-
This class is used to simplify the ImageHandler class.
|
4
|
-
Version: 0.1.6
|
5
|
-
"""
|
6
|
-
|
7
|
-
from __future__ import annotations
|
8
|
-
|
9
|
-
import logging
|
10
|
-
|
11
|
-
_LOGGER = logging.getLogger(__name__)
|
12
|
-
|
13
|
-
|
14
|
-
class ImageUtils:
|
15
|
-
"""Image Utils Class for Valetudo Hypfer Image Handler.
|
16
|
-
It is used to simplify the ImageHandler class."""
|
17
|
-
|
18
|
-
def __init__(self, image_handler):
|
19
|
-
self.img = image_handler
|
20
|
-
self.file_name = self.img.shared.file_name
|
21
|
-
|
22
|
-
def get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
|
23
|
-
"""Calculate the calibration points based on the rotation angle."""
|
24
|
-
|
25
|
-
# get_calibration_data
|
26
|
-
vacuum_points = [
|
27
|
-
{
|
28
|
-
"x": self.img.crop_area[0] + self.img.offset_x,
|
29
|
-
"y": self.img.crop_area[1] + self.img.offset_y,
|
30
|
-
}, # Top-left corner 0
|
31
|
-
{
|
32
|
-
"x": self.img.crop_area[2] - self.img.offset_x,
|
33
|
-
"y": self.img.crop_area[1] + self.img.offset_y,
|
34
|
-
}, # Top-right corner 1
|
35
|
-
{
|
36
|
-
"x": self.img.crop_area[2] - self.img.offset_x,
|
37
|
-
"y": self.img.crop_area[3] - self.img.offset_y,
|
38
|
-
}, # Bottom-right corner 2
|
39
|
-
{
|
40
|
-
"x": self.img.crop_area[0] + self.img.offset_x,
|
41
|
-
"y": self.img.crop_area[3] - self.img.offset_y,
|
42
|
-
}, # Bottom-left corner (optional)3
|
43
|
-
]
|
44
|
-
|
45
|
-
# Rotate the vacuum points based on the rotation angle
|
46
|
-
if rotation_angle == 90:
|
47
|
-
vacuum_points = [
|
48
|
-
vacuum_points[1],
|
49
|
-
vacuum_points[2],
|
50
|
-
vacuum_points[3],
|
51
|
-
vacuum_points[0],
|
52
|
-
]
|
53
|
-
elif rotation_angle == 180:
|
54
|
-
vacuum_points = [
|
55
|
-
vacuum_points[2],
|
56
|
-
vacuum_points[3],
|
57
|
-
vacuum_points[0],
|
58
|
-
vacuum_points[1],
|
59
|
-
]
|
60
|
-
elif rotation_angle == 270:
|
61
|
-
vacuum_points = [
|
62
|
-
vacuum_points[3],
|
63
|
-
vacuum_points[0],
|
64
|
-
vacuum_points[1],
|
65
|
-
vacuum_points[2],
|
66
|
-
]
|
67
|
-
|
68
|
-
return vacuum_points
|
69
|
-
|
70
|
-
def re_get_vacuum_points(self, rotation_angle: int) -> list[dict[str, int]]:
|
71
|
-
"""Recalculate the calibration points based on the rotation angle.
|
72
|
-
RAND256 Vacuums Calibration Points are in 10th of a mm."""
|
73
|
-
vacuum_points = [
|
74
|
-
{
|
75
|
-
"x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
|
76
|
-
"y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
|
77
|
-
}, # Top-left corner 0
|
78
|
-
{
|
79
|
-
"x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
|
80
|
-
"y": ((self.img.crop_area[1] + self.img.offset_y) * 10),
|
81
|
-
}, # Top-right corner 1
|
82
|
-
{
|
83
|
-
"x": ((self.img.crop_area[2] - self.img.offset_x) * 10),
|
84
|
-
"y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
|
85
|
-
}, # Bottom-right corner 2
|
86
|
-
{
|
87
|
-
"x": ((self.img.crop_area[0] + self.img.offset_x) * 10),
|
88
|
-
"y": ((self.img.crop_area[3] - self.img.offset_y) * 10),
|
89
|
-
}, # Bottom-left corner (optional)3
|
90
|
-
]
|
91
|
-
|
92
|
-
# Rotate the vacuum points based on the rotation angle
|
93
|
-
if rotation_angle == 90:
|
94
|
-
vacuum_points = [
|
95
|
-
vacuum_points[1],
|
96
|
-
vacuum_points[2],
|
97
|
-
vacuum_points[3],
|
98
|
-
vacuum_points[0],
|
99
|
-
]
|
100
|
-
elif rotation_angle == 180:
|
101
|
-
vacuum_points = [
|
102
|
-
vacuum_points[2],
|
103
|
-
vacuum_points[3],
|
104
|
-
vacuum_points[0],
|
105
|
-
vacuum_points[1],
|
106
|
-
]
|
107
|
-
elif rotation_angle == 270:
|
108
|
-
vacuum_points = [
|
109
|
-
vacuum_points[3],
|
110
|
-
vacuum_points[0],
|
111
|
-
vacuum_points[1],
|
112
|
-
vacuum_points[2],
|
113
|
-
]
|
114
|
-
|
115
|
-
return vacuum_points
|
116
|
-
|
117
|
-
def set_image_offset_ratio_1_1(
|
118
|
-
self, width: int, height: int, rand256: bool = False
|
119
|
-
) -> None:
|
120
|
-
"""Set the image offset ratio to 1:1."""
|
121
|
-
|
122
|
-
rotation = self.img.shared.image_rotate
|
123
|
-
if not rand256:
|
124
|
-
if rotation in [0, 180]:
|
125
|
-
self.img.offset_y = self.img.crop_img_size[0] - width
|
126
|
-
self.img.offset_x = (height - self.img.crop_img_size[1]) // 2
|
127
|
-
elif rotation in [90, 270]:
|
128
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
129
|
-
self.img.offset_x = (self.img.crop_img_size[1] - height) // 2
|
130
|
-
else:
|
131
|
-
if rotation in [0, 180]:
|
132
|
-
self.img.offset_x = (width - self.img.crop_img_size[0]) // 2
|
133
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
134
|
-
elif rotation in [90, 270]:
|
135
|
-
self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
|
136
|
-
self.img.offset_x = self.img.crop_img_size[1] - height
|
137
|
-
_LOGGER.debug(
|
138
|
-
"%s Image Coordinates Offsets (x,y): %s. %s",
|
139
|
-
self.file_name,
|
140
|
-
self.img.offset_x,
|
141
|
-
self.img.offset_y,
|
142
|
-
)
|
143
|
-
|
144
|
-
def set_image_offset_ratio_2_1(
|
145
|
-
self, width: int, height: int, rand256: bool = False
|
146
|
-
) -> None:
|
147
|
-
"""Set the image offset ratio to 2:1."""
|
148
|
-
|
149
|
-
rotation = self.img.shared.image_rotate
|
150
|
-
if not rand256:
|
151
|
-
if rotation in [0, 180]:
|
152
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
153
|
-
self.img.offset_x = height - self.img.crop_img_size[1]
|
154
|
-
elif rotation in [90, 270]:
|
155
|
-
self.img.offset_x = width - self.img.crop_img_size[0]
|
156
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
157
|
-
else:
|
158
|
-
if rotation in [0, 180]:
|
159
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
160
|
-
self.img.offset_x = height - self.img.crop_img_size[1]
|
161
|
-
elif rotation in [90, 270]:
|
162
|
-
self.img.offset_x = width - self.img.crop_img_size[0]
|
163
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
164
|
-
|
165
|
-
_LOGGER.debug(
|
166
|
-
"%s Image Coordinates Offsets (x,y): %s. %s",
|
167
|
-
self.file_name,
|
168
|
-
self.img.offset_x,
|
169
|
-
self.img.offset_y,
|
170
|
-
)
|
171
|
-
|
172
|
-
def set_image_offset_ratio_3_2(
|
173
|
-
self, width: int, height: int, rand256: bool = False
|
174
|
-
) -> None:
|
175
|
-
"""Set the image offset ratio to 3:2."""
|
176
|
-
|
177
|
-
rotation = self.img.shared.image_rotate
|
178
|
-
|
179
|
-
if not rand256:
|
180
|
-
if rotation in [0, 180]:
|
181
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
182
|
-
self.img.offset_x = ((height - self.img.crop_img_size[1]) // 2) - (
|
183
|
-
self.img.crop_img_size[1] // 10
|
184
|
-
)
|
185
|
-
elif rotation in [90, 270]:
|
186
|
-
self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
|
187
|
-
self.img.offset_x = (self.img.crop_img_size[1] - height) + (
|
188
|
-
(height // 10) // 2
|
189
|
-
)
|
190
|
-
else:
|
191
|
-
if rotation in [0, 180]:
|
192
|
-
self.img.offset_x = (width - self.img.crop_img_size[0]) // 2
|
193
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
194
|
-
elif rotation in [90, 270]:
|
195
|
-
self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
|
196
|
-
self.img.offset_x = self.img.crop_img_size[1] - height
|
197
|
-
|
198
|
-
_LOGGER.debug(
|
199
|
-
"%s Image Coordinates Offsets (x,y): %s. %s",
|
200
|
-
self.file_name,
|
201
|
-
self.img.offset_x,
|
202
|
-
self.img.offset_y,
|
203
|
-
)
|
204
|
-
|
205
|
-
def set_image_offset_ratio_5_4(
|
206
|
-
self, width: int, height: int, rand256: bool = False
|
207
|
-
) -> None:
|
208
|
-
"""Set the image offset ratio to 5:4."""
|
209
|
-
|
210
|
-
rotation = self.img.shared.image_rotate
|
211
|
-
if not rand256:
|
212
|
-
if rotation in [0, 180]:
|
213
|
-
self.img.offset_x = ((width - self.img.crop_img_size[0]) // 2) - (
|
214
|
-
self.img.crop_img_size[0] // 2
|
215
|
-
)
|
216
|
-
self.img.offset_y = (self.img.crop_img_size[1] - height) - (
|
217
|
-
self.img.crop_img_size[1] // 2
|
218
|
-
)
|
219
|
-
elif rotation in [90, 270]:
|
220
|
-
self.img.offset_y = ((self.img.crop_img_size[0] - width) // 2) - 10
|
221
|
-
self.img.offset_x = (self.img.crop_img_size[1] - height) + (
|
222
|
-
height // 10
|
223
|
-
)
|
224
|
-
else:
|
225
|
-
if rotation in [0, 180]:
|
226
|
-
self.img.offset_y = (width - self.img.crop_img_size[0]) // 2
|
227
|
-
self.img.offset_x = self.img.crop_img_size[1] - height
|
228
|
-
elif rotation in [90, 270]:
|
229
|
-
self.img.offset_y = (self.img.crop_img_size[0] - width) // 2
|
230
|
-
self.img.offset_x = self.img.crop_img_size[1] - height
|
231
|
-
|
232
|
-
_LOGGER.debug(
|
233
|
-
"%s Image Coordinates Offsets (x,y): %s. %s",
|
234
|
-
self.file_name,
|
235
|
-
self.img.offset_x,
|
236
|
-
self.img.offset_y,
|
237
|
-
)
|
238
|
-
|
239
|
-
def set_image_offset_ratio_9_16(
|
240
|
-
self, width: int, height: int, rand256: bool = False
|
241
|
-
) -> None:
|
242
|
-
"""Set the image offset ratio to 9:16."""
|
243
|
-
|
244
|
-
rotation = self.img.shared.image_rotate
|
245
|
-
if not rand256:
|
246
|
-
if rotation in [0, 180]:
|
247
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
248
|
-
self.img.offset_x = height - self.img.crop_img_size[1]
|
249
|
-
elif rotation in [90, 270]:
|
250
|
-
self.img.offset_x = (width - self.img.crop_img_size[0]) + (height // 10)
|
251
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
252
|
-
else:
|
253
|
-
if rotation in [0, 180]:
|
254
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
255
|
-
self.img.offset_x = height - self.img.crop_img_size[1]
|
256
|
-
elif rotation in [90, 270]:
|
257
|
-
self.img.offset_x = width - self.img.crop_img_size[0]
|
258
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
259
|
-
|
260
|
-
_LOGGER.debug(
|
261
|
-
"%s Image Coordinates Offsets (x,y): %s. %s",
|
262
|
-
self.file_name,
|
263
|
-
self.img.offset_x,
|
264
|
-
self.img.offset_y,
|
265
|
-
)
|
266
|
-
|
267
|
-
def set_image_offset_ratio_16_9(
|
268
|
-
self, width: int, height: int, rand256: bool = False
|
269
|
-
) -> None:
|
270
|
-
"""Set the image offset ratio to 16:9."""
|
271
|
-
|
272
|
-
rotation = self.img.shared.image_rotate
|
273
|
-
if not rand256:
|
274
|
-
if rotation in [0, 180]:
|
275
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
276
|
-
self.img.offset_x = height - self.img.crop_img_size[1]
|
277
|
-
elif rotation in [90, 270]:
|
278
|
-
self.img.offset_x = width - self.img.crop_img_size[0]
|
279
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
280
|
-
else:
|
281
|
-
if rotation in [0, 180]:
|
282
|
-
self.img.offset_y = width - self.img.crop_img_size[0]
|
283
|
-
self.img.offset_x = height - self.img.crop_img_size[1]
|
284
|
-
elif rotation in [90, 270]:
|
285
|
-
self.img.offset_x = width - self.img.crop_img_size[0]
|
286
|
-
self.img.offset_y = height - self.img.crop_img_size[1]
|
287
|
-
|
288
|
-
_LOGGER.debug(
|
289
|
-
"%s Image Coordinates Offsets (x,y): %s. %s",
|
290
|
-
self.file_name,
|
291
|
-
self.img.offset_x,
|
292
|
-
self.img.offset_y,
|
293
|
-
)
|
294
|
-
|
295
|
-
async def async_zone_propriety(self, zones_data) -> dict:
|
296
|
-
"""Get the zone propriety"""
|
297
|
-
zone_properties = {}
|
298
|
-
id_count = 1
|
299
|
-
for zone in zones_data:
|
300
|
-
zone_name = zone.get("name")
|
301
|
-
coordinates = zone.get("coordinates")
|
302
|
-
if coordinates and len(coordinates) > 0:
|
303
|
-
coordinates[0].pop()
|
304
|
-
x1, y1, x2, y2 = coordinates[0]
|
305
|
-
zone_properties[zone_name] = {
|
306
|
-
"zones": coordinates,
|
307
|
-
"name": zone_name,
|
308
|
-
"x": ((x1 + x2) // 2),
|
309
|
-
"y": ((y1 + y2) // 2),
|
310
|
-
}
|
311
|
-
id_count += 1
|
312
|
-
if id_count > 1:
|
313
|
-
_LOGGER.debug("%s: Zones Properties updated.", self.file_name)
|
314
|
-
return zone_properties
|
315
|
-
|
316
|
-
async def async_points_propriety(self, points_data) -> dict:
|
317
|
-
"""Get the point propriety"""
|
318
|
-
point_properties = {}
|
319
|
-
id_count = 1
|
320
|
-
for point in points_data:
|
321
|
-
point_name = point.get("name")
|
322
|
-
coordinates = point.get("coordinates")
|
323
|
-
if coordinates and len(coordinates) > 0:
|
324
|
-
coordinates = point.get("coordinates")
|
325
|
-
x1, y1 = coordinates
|
326
|
-
point_properties[id_count] = {
|
327
|
-
"position": coordinates,
|
328
|
-
"name": point_name,
|
329
|
-
"x": x1,
|
330
|
-
"y": y1,
|
331
|
-
}
|
332
|
-
id_count += 1
|
333
|
-
if id_count > 1:
|
334
|
-
_LOGGER.debug("%s: Point Properties updated.", self.file_name)
|
335
|
-
return point_properties
|
File without changes
|
File without changes
|
File without changes
|