linzheng commited on
Commit
cdac6db
·
verified ·
1 Parent(s): a3db85f

Upload processor

Browse files
image_processing_evabyte.py ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ """Image processor class for EvaByte."""
3
+
4
+ from typing import Dict, List, Optional, Union, Tuple
5
+
6
+ import io
7
+ from transformers.image_processing_utils import BaseImageProcessor
8
+ from transformers.image_utils import (
9
+ ImageInput,
10
+ PILImageResampling,
11
+ valid_images,
12
+ validate_preprocess_arguments,
13
+ )
14
+ from PIL import Image
15
+
16
+ def _get_qtable_bytes():
17
+ return {
18
+ 5: b'\xff\xd8\xff\xdb\x00C\x00\xa0nx\x8cxd\xa0\x8c\x82\x8c\xb4\xaa\xa0\xbe\xf0\xff\xff\xf0\xdc\xdc\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdb\x00C\x01\xa0\xb4\xb4\xf0\xd2\xf0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd9',
19
+ 10: b'\xff\xd8\xff\xdb\x00C\x00P7<F<2PFAFZUP_x\xc8\x82xnnx\xf5\xaf\xb9\x91\xc8\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdb\x00C\x01PZZxix\xeb\x82\x82\xeb\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd9',
20
+ 15: b'\xff\xd8\xff\xdb\x00C\x005%(/(!5/+/<95?P\x85WPIIP\xa3u{a\x85\xc1\xaa\xcb\xc8\xbe\xaa\xba\xb7\xd5\xf0\xff\xff\xd5\xe2\xff\xe6\xb7\xba\xff\xff\xff\xff\xff\xff\xff\xff\xff\xce\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdb\x00C\x015<<PFP\x9dWW\x9d\xff\xdc\xba\xdc\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd9',
21
+ 20: b'\xff\xd8\xff\xdb\x00C\x00(\x1c\x1e#\x1e\x19(#!#-+(0<dA<77<{X]Id\x91\x80\x99\x96\x8f\x80\x8c\x8a\xa0\xb4\xe6\xc3\xa0\xaa\xda\xad\x8a\x8c\xc8\xff\xcb\xda\xee\xf5\xff\xff\xff\x9b\xc1\xff\xff\xff\xfa\xff\xe6\xfd\xff\xf8\xff\xdb\x00C\x01(--<5<vAAv\xf8\xa5\x8c\xa5\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xf8\xff\xd9',
22
+ 25: b'\xff\xd8\xff\xdb\x00C\x00 \x16\x18\x1c\x18\x14 \x1c\x1a\x1c$" &0P40,,0bFJ:Ptfzxrfpn\x80\x90\xb8\x9c\x80\x88\xae\x8anp\xa0\xda\xa2\xae\xbe\xc4\xce\xd0\xce|\x9a\xe2\xf2\xe0\xc8\xf0\xb8\xca\xce\xc6\xff\xdb\x00C\x01 $$0*0^44^\xc6\x84p\x84\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xc6\xff\xd9',
23
+ 30: b'\xff\xd8\xff\xdb\x00C\x00\x1b\x12\x14\x17\x14\x11\x1b\x17\x16\x17\x1e\x1c\x1b (B+(%%(Q:=0B`Ued_U][jx\x99\x81jq\x90s[]\x85\xb5\x86\x90\x9e\xa3\xab\xad\xabg\x80\xbc\xc9\xba\xa6\xc7\x99\xa8\xab\xa4\xff\xdb\x00C\x01\x1b\x1e\x1e(#(N++N\xa4n]n\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xa4\xff\xd9',
24
+ 50: b'\xff\xd8\xff\xdb\x00C\x00\x10\x0b\x0c\x0e\x0c\n\x10\x0e\r\x0e\x12\x11\x10\x13\x18(\x1a\x18\x16\x16\x181#%\x1d(:3=<9387@H\\N@DWE78PmQW_bghg>Mqypdx\\egc\xff\xdb\x00C\x01\x10\x12\x12\x18\x15\x18/\x1a\x1a/cB8Bcccccccccccccccccccccccccccccccccccccccccccccccccc\xff\xd9',
25
+ 75: b'\xff\xd8\xff\xdb\x00C\x00\x08\x06\x06\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f\x14\x1d\x1a\x1f\x1e\x1d\x1a\x1c\x1c $.\' ",#\x1c\x1c(7),01444\x1f\'9=82<.342\xff\xdb\x00C\x01\x08\t\t\x0c\x0b\x0c\x18\r\r\x182!\x1c!22222222222222222222222222222222222222222222222222\xff\xd9',
26
+ 95: b'\xff\xd8\xff\xdb\x00C\x00\x02\x01\x01\x01\x01\x01\x02\x01\x01\x01\x02\x02\x02\x02\x02\x04\x03\x02\x02\x02\x02\x05\x04\x04\x03\x04\x06\x05\x06\x06\x06\x05\x06\x06\x06\x07\t\x08\x06\x07\t\x07\x06\x06\x08\x0b\x08\t\n\n\n\n\n\x06\x08\x0b\x0c\x0b\n\x0c\t\n\n\n\xff\xdb\x00C\x01\x02\x02\x02\x02\x02\x02\x05\x03\x03\x05\n\x07\x06\x07\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\xff\xd9',
27
+ 100: b'\xff\xd8\xff\xdb\x00C\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xff\xdb\x00C\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\xff\xd9',
28
+ }
29
+
30
+
31
+ def _resize_if_exceeding_max_len(
32
+ width: int, height: int, min_len: Optional[int] = 16, max_len: Optional[int] = None
33
+ ) -> Tuple[int, int]:
34
+ """
35
+ Get the output size of the image after resizing given a dictionary specifying the max and min sizes.
36
+
37
+ Args:
38
+ height (`int`):
39
+ Height of the input image.
40
+ width (`int`):
41
+ Width of the input image.
42
+ max_len (`Dict[str, int]`, *optional*, defaults to the maximum size of the image):
43
+ Defines the maximum dimensions of the image.
44
+
45
+ Returns:
46
+ The output size of the image after resizing.
47
+ """
48
+ max_len = max(height, width) if max_len is None else max_len
49
+ aspect_ratio = width / height
50
+
51
+ if width >= height and width > max_len:
52
+ width = max_len
53
+ height = int(width / aspect_ratio)
54
+ if height % 2 != 0:
55
+ height += 1
56
+ elif height > width and height > max_len:
57
+ height = max_len
58
+ width = int(height * aspect_ratio)
59
+ if width % 2 != 0:
60
+ width += 1
61
+
62
+ # Avoid resizing to a size smaller than 1
63
+ height = max(height, min_len)
64
+ width = max(width, min_len)
65
+ return width, height
66
+
67
+ class EvaByteImageProcessor(BaseImageProcessor):
68
+
69
+ model_input_names = []
70
+
71
+ def __init__(
72
+ self,
73
+ do_resize: bool = True,
74
+ resample: PILImageResampling = PILImageResampling.LANCZOS,
75
+ size: Dict[str, int] = None,
76
+ do_convert_rgb: bool = True,
77
+ jpeg_quality: int = 25,
78
+ jpeg_subsampling: str = "4:2:0",
79
+ jpeg_streamtype: str = 2,
80
+ jpeg_restart_marker_blocks: int = 1,
81
+ **kwargs,
82
+ ) -> None:
83
+ super().__init__(**kwargs)
84
+ self.do_resize = do_resize
85
+ self.resample = resample
86
+ self.size = size if size is not None else {"longest_edge": 384}
87
+ self.do_convert_rgb = do_convert_rgb
88
+ self.jpeg_quality = jpeg_quality
89
+ self.jpeg_subsampling = jpeg_subsampling
90
+ self.jpeg_streamtype = jpeg_streamtype
91
+ self.jpeg_restart_marker_blocks = jpeg_restart_marker_blocks
92
+
93
+ def jpeg_encode(
94
+ self,
95
+ image,
96
+ jpeg_quality,
97
+ jpeg_subsampling,
98
+ jpeg_streamtype,
99
+ jpeg_restart_marker_blocks,
100
+ ):
101
+ with io.BytesIO() as output:
102
+ image.save(
103
+ output,
104
+ format="JPEG",
105
+ quality=jpeg_quality,
106
+ subsampling=jpeg_subsampling,
107
+ streamtype=jpeg_streamtype,
108
+ restart_marker_blocks=jpeg_restart_marker_blocks
109
+ )
110
+ jpeg_bytes = output.getvalue()
111
+ return jpeg_bytes
112
+
113
+ def jpeg_merge_qtables(
114
+ self,
115
+ image_bytes,
116
+ jpeg_quality=None,
117
+ ):
118
+ if jpeg_quality is None:
119
+ jpeg_quality = self.jpeg_quality
120
+ qtable_bytes = _get_qtable_bytes()[jpeg_quality]
121
+ return image_bytes[:2] + qtable_bytes[2:-2] + image_bytes[2:]
122
+
123
+ def resize(
124
+ self,
125
+ image: Image,
126
+ size: Dict[str, int],
127
+ resample: PILImageResampling = PILImageResampling.LANCZOS,
128
+ ) -> Image:
129
+ if "longest_edge" in size:
130
+ width, height = image.size
131
+ # Find the output size, when rescaling the longest edge to max_len and preserving the aspect ratio
132
+ width, height = _resize_if_exceeding_max_len(width, height, max_len=size["longest_edge"])
133
+ size = (width, height)
134
+ elif "width" in size and "height" in size:
135
+ size = (size["width"], size["height"])
136
+ else:
137
+ raise ValueError("size must be a dictionary with key 'longest_edge' or 'height' and 'width'.")
138
+ resized_image = image.resize(size, resample=resample)
139
+ return resized_image
140
+
141
+ def preprocess(
142
+ self,
143
+ images: ImageInput,
144
+ do_resize: bool = None,
145
+ resample = None,
146
+ size: Dict[str, int] = None,
147
+ do_convert_rgb: bool = None,
148
+ jpeg_quality: int = None,
149
+ jpeg_subsampling: str = None,
150
+ jpeg_streamtype: str = None,
151
+ jpeg_restart_marker_blocks: int = None,
152
+ ):
153
+ do_resize = do_resize if do_resize is not None else self.do_resize
154
+ size = size if size is not None else self.size
155
+ resample = resample if resample is not None else self.resample
156
+ do_convert_rgb = do_convert_rgb if do_convert_rgb is not None else self.do_convert_rgb
157
+
158
+ jpeg_quality = jpeg_quality if jpeg_quality is not None else self.jpeg_quality
159
+ jpeg_subsampling = jpeg_subsampling if jpeg_subsampling is not None else self.jpeg_subsampling
160
+ jpeg_streamtype = jpeg_streamtype if jpeg_streamtype is not None else self.jpeg_streamtype
161
+ jpeg_restart_marker_blocks = jpeg_restart_marker_blocks if jpeg_restart_marker_blocks is not None else self.jpeg_restart_marker_blocks
162
+
163
+ if images is not None and not valid_images(images):
164
+ raise ValueError(
165
+ "Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, "
166
+ "torch.Tensor, tf.Tensor or jax.ndarray."
167
+ )
168
+
169
+ validate_preprocess_arguments(
170
+ do_resize=do_resize,
171
+ size=size,
172
+ resample=resample,
173
+ )
174
+ images_list = images
175
+ if do_convert_rgb:
176
+ images_list = [
177
+ [
178
+ image.convert("RGB") for image in images
179
+ ]
180
+ for images in images_list
181
+ ]
182
+
183
+ if do_resize:
184
+ images_list = [
185
+ [
186
+ self.resize(image=image, size=size, resample=resample)
187
+ for image in images
188
+ ]
189
+ for images in images_list
190
+ ]
191
+
192
+ jpeg_bytes = [
193
+ [
194
+ self.jpeg_encode(
195
+ image,
196
+ jpeg_quality,
197
+ jpeg_subsampling,
198
+ jpeg_streamtype,
199
+ jpeg_restart_marker_blocks
200
+ ) for image in images
201
+ ]
202
+ for images in images_list
203
+ ]
204
+ return jpeg_bytes
preprocessor_config.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "auto_map": {
3
+ "AutoImageProcessor": "image_processing_evabyte.EvaByteImageProcessor"
4
+ },
5
+ "do_convert_rgb": true,
6
+ "do_resize": true,
7
+ "image_processor_type": "EvaByteImageProcessor",
8
+ "jpeg_quality": 25,
9
+ "jpeg_restart_marker_blocks": 1,
10
+ "jpeg_streamtype": 2,
11
+ "jpeg_subsampling": "4:2:0",
12
+ "resample": 1,
13
+ "size": {
14
+ "longest_edge": 384
15
+ }
16
+ }