Skip to content

Commit 7d9b273

Browse files
committed
jpeg quality is now 90% by default and can be overridden with IDC_JPEG_QUALITY environment variable; centralized converting image from array back to PILLOW Image and creation of empty image
1 parent 110e9b5 commit 7d9b273

8 files changed

Lines changed: 31 additions & 45 deletions

File tree

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changelog
55
------------------
66

77
- switched to underscores in project name
8+
- switched to new methods from idc.api: `empty_image(...)` and `arary_to_image(...)`
89

910

1011
0.0.4 (2024-07-16)

src/idc/imgaug/filter/_augment_util.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
import io
2-
31
import imageio.v2 as imageio
4-
import numpy as np
5-
from PIL import Image
62
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage
73
from imgaug.augmentables.polys import Polygon, PolygonsOnImage
84
from imgaug.augmentables.segmaps import SegmentationMapsOnImage
95
from wai.common.adams.imaging.locateobjects import LocatedObjects, absolute_to_normalized
106
from wai.common.geometry import Point as WaiPoint
117
from wai.common.geometry import Polygon as WaiPolygon
128

13-
from idc.api import ImageData, ObjectDetectionData, ImageSegmentationData, combine_layers, split_layers
9+
from idc.api import ImageData, ObjectDetectionData, ImageSegmentationData, combine_layers, split_layers, array_to_image
1410

1511

1612
def augment_image(item: ImageData, pipeline, image_name: str = None) -> ImageData:
@@ -133,9 +129,7 @@ def augment_image(item: ImageData, pipeline, image_name: str = None) -> ImageDat
133129
if (objs_aug is not None) and normalized:
134130
annotation_new = absolute_to_normalized(annotation_new, item.image_width, item.image_height)
135131

136-
img_new = Image.fromarray(np.uint8(image_aug))
137-
img_new_bytes = io.BytesIO()
138-
img_new.save(img_new_bytes, format=item.image_format)
132+
_, img_new_bytes = array_to_image(image_aug, item.image_format)
139133

140134
result = type(item)(image_name=image_name, data=img_new_bytes.getvalue(),
141135
image_format=item.image_format,

src/idc/imgaug/filter/_change_grayscale.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from seppl.io import Filter
88
from wai.logging import LOGGING_WARNING
99

10-
from idc.api import ImageClassificationData, ObjectDetectionData, ImageSegmentationData, flatten_list, make_list
10+
from idc.api import ImageClassificationData, ObjectDetectionData, ImageSegmentationData, flatten_list, make_list, array_to_image
1111

1212

1313
class ChangeGrayscale(Filter):
@@ -117,9 +117,7 @@ def _do_process(self, data):
117117
else:
118118
img_gray = img_gray + self.increment
119119
img_gray = np.clip(img_gray, 0, 255).astype(np.uint8)
120-
img_pil = Image.fromarray(np.uint8(img_gray))
121-
img_pil_bytes = io.BytesIO()
122-
img_pil.save(img_pil_bytes, format=item.image_format)
120+
_, img_pil_bytes = array_to_image(img_gray, item.image_format)
123121
item_new = type(item)(image_name=item.image_name, data=img_pil_bytes.getvalue(),
124122
metadata=item.get_metadata(), annotation=item.annotation)
125123
result.append(item_new)

src/idc/imgaug/filter/_clip_grayscale.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import argparse
2-
import io
32
from typing import List
43

54
import numpy as np
6-
from PIL import Image
75
from seppl.io import Filter
86
from wai.logging import LOGGING_WARNING
97

10-
from idc.api import ImageClassificationData, ObjectDetectionData, ImageSegmentationData, flatten_list, make_list
8+
from idc.api import ImageClassificationData, ObjectDetectionData, ImageSegmentationData, flatten_list, make_list, \
9+
array_to_image
1110

1211

1312
class ClipGrayscale(Filter):
@@ -142,9 +141,7 @@ def _do_process(self, data):
142141
if self.max_value < 255:
143142
img_gray = np.where(img_gray > self.max_value, self.max_replacement, img_gray)
144143
img_gray = np.clip(img_gray, 0, 255).astype(np.uint8)
145-
img_pil = Image.fromarray(np.uint8(img_gray))
146-
img_pil_bytes = io.BytesIO()
147-
img_pil.save(img_pil_bytes, format=item.image_format)
144+
_, img_pil_bytes = array_to_image(img_gray, item.image_format)
148145
item_new = type(item)(image_name=item.image_name, data=img_pil_bytes.getvalue(),
149146
metadata=item.get_metadata(), annotation=item.annotation)
150147
result.append(item_new)

src/idc/imgaug/filter/_enhance.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from PIL import ImageEnhance
99
from ._base_image_augmentation import BaseFilter, IMGAUG_MODE_REPLACE
1010
from wai.logging import LOGGING_WARNING
11-
from idc.api import ImageData, ImageClassificationData, ObjectDetectionData, ImageSegmentationData
11+
from idc.api import ImageData, ImageClassificationData, ObjectDetectionData, ImageSegmentationData, array_to_image
1212

1313
ENHANCEMENT_COLOR = "color"
1414
ENHANCEMENT_CONTRAST = "contrast"
@@ -184,9 +184,7 @@ def _augment(self, item: ImageData, aug_seed: int, image_name: str) -> ImageData
184184
img_enhanced = enhancer.enhance(factor)
185185

186186
# convert back to PIL bytes
187-
img_pil = Image.fromarray(np.uint8(img_enhanced))
188-
img_pil_bytes = io.BytesIO()
189-
img_pil.save(img_pil_bytes, format=item.image_format)
187+
_, img_pil_bytes = array_to_image(img_enhanced, item.image_format)
190188
result = type(item)(image_name=image_name, data=img_pil_bytes.getvalue(),
191189
image_format=item.image_format,
192190
metadata=item.get_metadata(), annotation=item.annotation)

src/idc/imgaug/filter/_hsl_grayscale.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import argparse
2-
import cv2
3-
import io
4-
import numpy as np
52
from random import Random
63
from typing import List
74

8-
from PIL import Image
9-
from ._base_image_augmentation import BaseFilter, IMGAUG_MODE_REPLACE
5+
import cv2
6+
import numpy as np
107
from wai.logging import LOGGING_WARNING
11-
from idc.api import ImageData, ImageClassificationData, ObjectDetectionData, ImageSegmentationData
8+
9+
from idc.api import ImageData, ImageClassificationData, ObjectDetectionData, ImageSegmentationData, array_to_image
10+
from ._base_image_augmentation import BaseFilter, IMGAUG_MODE_REPLACE
1211

1312

1413
class HSLGrayScale(BaseFilter):
@@ -159,9 +158,7 @@ def _augment(self, item: ImageData, aug_seed: int, image_name: str) -> ImageData
159158
img_l = img_l.astype(np.uint8)
160159

161160
# convert back to PIL bytes
162-
img_pil = Image.fromarray(np.uint8(img_l))
163-
img_pil_bytes = io.BytesIO()
164-
img_pil.save(img_pil_bytes, format=item.image_format)
161+
_, img_pil_bytes = array_to_image(img_l, item.image_format)
165162
result = type(item)(image_name=image_name, data=img_pil_bytes.getvalue(),
166163
image_format=item.image_format,
167164
metadata=item.get_metadata(), annotation=item.annotation)

src/idc/imgaug/filter/_sub_images_utils.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import io
21
import logging
32
import os
43
from typing import List, Tuple, Optional
54

65
import numpy as np
7-
from PIL import Image
86
from wai.common.adams.imaging.locateobjects import LocatedObject, LocatedObjects
97
from wai.common.geometry import Point as WaiPoint, Polygon as WaiPolygon
108

119
from idc.api import ImageSegmentationAnnotations, ImageClassificationData, ImageSegmentationData, ObjectDetectionData, \
12-
ImageData, crop_image, pad_image, fit_layers, fit_located_object
10+
ImageData, crop_image, pad_image, fit_layers, fit_located_object, array_to_image, empty_image
11+
import logging
12+
import os
13+
from typing import List, Tuple, Optional
14+
15+
import numpy as np
16+
from wai.common.adams.imaging.locateobjects import LocatedObject, LocatedObjects
17+
from wai.common.geometry import Point as WaiPoint, Polygon as WaiPolygon
18+
19+
from idc.api import ImageSegmentationAnnotations, ImageClassificationData, ImageSegmentationData, ObjectDetectionData, \
20+
ImageData, crop_image, pad_image, fit_layers, fit_located_object, array_to_image, empty_image
1321

1422
REGION_SORTING_NONE = "none"
1523
REGION_SORTING_XY = "x-then-y"
@@ -162,8 +170,7 @@ def process_image(item: ImageData, regions_lobj: List[LocatedObject], regions_xy
162170
sub_image = pil.crop((x0, y0, x1+1, y1+1))
163171
orig_dims = LocatedObject(0, 0, sub_image.size[0], sub_image.size[1])
164172
sub_image = pad_image(sub_image, pad_width=pad_width, pad_height=pad_height)
165-
sub_bytes = io.BytesIO()
166-
sub_image.save(sub_bytes, format=item.image_format)
173+
_, sub_bytes = array_to_image(sub_image, item.image_format)
167174
image_name_new = region_filename(item.image_name, regions_lobj, regions_xyxy, region_index, suffix)
168175

169176
# crop annotations and forward
@@ -214,9 +221,7 @@ def new_from_template(item, rebuild_image: bool = False):
214221
:return: the new container
215222
"""
216223
if rebuild_image:
217-
img = Image.new(item.image.mode, item.image_size)
218-
img_bytes = io.BytesIO()
219-
img.save(img_bytes, format=item.image_format)
224+
_, img_bytes = empty_image(item.image.mode, item.image_width, item.image_height, item.image_format)
220225
data = img_bytes.getvalue()
221226
else:
222227
data = item.image_bytes

src/idc/imgaug/tool/combine_sub_images.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import argparse
2-
import io
32
import logging
43
import os.path
54
import re
65
import sys
76
import traceback
87
from typing import List, Dict, Tuple
98

10-
from PIL import Image
119
from seppl import Initializable, init_initializable, Session
1210
from seppl.io import locate_files, StreamWriter, BatchWriter, Writer
1311
from wai.common.adams.imaging.locateobjects import LocatedObject
1412
from wai.logging import init_logging, set_logging_level, add_logging_level
1513

16-
from idc.api import ImageData, parse_reader, parse_writer, Reader, ObjectDetectionData, merge_polygons
14+
from idc.api import ImageData, parse_reader, parse_writer, Reader, ObjectDetectionData, merge_polygons, empty_image
1715
from idc.core import ENV_IDC_LOGLEVEL
1816
from idc.imgaug.filter import new_from_template, transfer_region
1917

@@ -129,9 +127,7 @@ def merge_images(input_images: List[ImageData], coordinates: [List[Tuple[int, in
129127
:return: the combined image/annotations
130128
:rtype: ImageData
131129
"""
132-
full_img = Image.new("RGB", (width, height))
133-
img_bytes = io.BytesIO()
134-
full_img.save(img_bytes, format=input_images[0].image_format)
130+
_, img_bytes = empty_image("RGB", width, height, input_images[0].image_format)
135131
data = img_bytes.getvalue()
136132

137133
cls = type(input_images[0])

0 commit comments

Comments
 (0)