|
15 | 15 | import numpy as np |
16 | 16 | from augly import utils |
17 | 17 | from augly.image import utils as imutils |
| 18 | +from augly.image.utils.bboxes import spatial_bbox_helper |
18 | 19 | from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont |
19 | 20 |
|
20 | 21 |
|
@@ -2368,6 +2369,72 @@ def shuffle_pixels( |
2368 | 2369 | return imutils.ret_and_save_image(aug_image, output_path, src_mode) |
2369 | 2370 |
|
2370 | 2371 |
|
| 2372 | +def skew( |
| 2373 | + image: Union[str, Image.Image], |
| 2374 | + output_path: Optional[str] = None, |
| 2375 | + skew_factor: float = 0.5, |
| 2376 | + axis: int = 0, |
| 2377 | + metadata: Optional[List[Dict[str, Any]]] = None, |
| 2378 | + bboxes: Optional[List[Tuple]] = None, |
| 2379 | + bbox_format: Optional[str] = None, |
| 2380 | +) -> Image.Image: |
| 2381 | + """ |
| 2382 | + Skews an image with respect to its x or y-axis |
| 2383 | +
|
| 2384 | + @param image: the path to an image or a variable of type PIL.Image.Image |
| 2385 | + to be augmented |
| 2386 | +
|
| 2387 | + @param output_path: the path in which the resulting image will be stored. |
| 2388 | + If None, the resulting PIL Image will still be returned |
| 2389 | +
|
| 2390 | + @param skew_factor: the level of skew to apply to the image; a larger absolute value will |
| 2391 | + result in a more intense skew. Recommended range is between [-2, 2] |
| 2392 | +
|
| 2393 | + @param axis: the axis along which the image will be skewed; can be set to 0 (x-axis) |
| 2394 | + or 1 (y-axis) |
| 2395 | +
|
| 2396 | + @param metadata: if set to be a list, metadata about the function execution |
| 2397 | + including its name, the source & dest width, height, etc. will be appended |
| 2398 | + to the inputted list. If set to None, no metadata will be appended or returned |
| 2399 | +
|
| 2400 | + @param bboxes: a list of bounding boxes can be passed in here if desired. If |
| 2401 | + provided, this list will be modified in place such that each bounding box is |
| 2402 | + transformed according to this function |
| 2403 | +
|
| 2404 | + @param bbox_format: signifies what bounding box format was used in `bboxes`. Must |
| 2405 | + specify `bbox_format` if `bboxes` is provided. Supported bbox_format values are |
| 2406 | + "pascal_voc", "pascal_voc_norm", "coco", and "yolo" |
| 2407 | +
|
| 2408 | + @returns: the augmented PIL Image |
| 2409 | + """ |
| 2410 | + image = imutils.validate_and_load_image(image) |
| 2411 | + func_kwargs = imutils.get_func_kwargs(metadata, locals()) |
| 2412 | + src_mode = image.mode |
| 2413 | + |
| 2414 | + w, h = image.size |
| 2415 | + |
| 2416 | + if axis == 0: |
| 2417 | + data = (1, skew_factor, -skew_factor * h / 2, 0, 1, 0) |
| 2418 | + elif axis == 1: |
| 2419 | + data = (1, 0, 0, skew_factor, 1, -skew_factor * w / 2) |
| 2420 | + else: |
| 2421 | + raise AssertionError( |
| 2422 | + f"Invalid 'axis' value: Got '{axis}', expected 0 for 'x-axis' or 1 for 'y-axis'" |
| 2423 | + ) |
| 2424 | + |
| 2425 | + aug_image = image.transform((w, h), Image.AFFINE, data, resample=Image.BILINEAR) |
| 2426 | + imutils.get_metadata( |
| 2427 | + metadata=metadata, |
| 2428 | + function_name="skew", |
| 2429 | + aug_image=aug_image, |
| 2430 | + bboxes_helper_func=spatial_bbox_helper, |
| 2431 | + aug_function=skew, |
| 2432 | + **func_kwargs, |
| 2433 | + ) |
| 2434 | + |
| 2435 | + return imutils.ret_and_save_image(aug_image, output_path, src_mode) # pyre-ignore |
| 2436 | + |
| 2437 | + |
2371 | 2438 | def vflip( |
2372 | 2439 | image: Union[str, Image.Image], |
2373 | 2440 | output_path: Optional[str] = None, |
|
0 commit comments