You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

py_transforms.py 69 kB

5 years ago
5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742
  1. # Copyright 2019 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ==============================================================================
  15. """
  16. The module vision.py_transforms is mainly implemented based on Python PIL, which
  17. provides many kinds of image augmentation methods and conversion methods between
  18. PIL image and numpy.ndarray. For users who prefer using Python PIL in computer vision
  19. tasks, this module is a good choice to process images. Users can also self-define
  20. their own augmentation methods with Python PIL.
  21. """
  22. import numbers
  23. import random
  24. import numpy as np
  25. from PIL import Image
  26. import mindspore.dataset.transforms.py_transforms as py_transforms
  27. from . import py_transforms_util as util
  28. from .c_transforms import parse_padding
  29. from .validators import check_prob, check_center_crop, check_five_crop, check_resize_interpolation, check_random_resize_crop, \
  30. check_normalize_py, check_normalizepad_py, check_random_crop, check_random_color_adjust, check_random_rotation, \
  31. check_ten_crop, check_num_channels, check_pad, check_rgb_to_hsv, check_hsv_to_rgb, check_alpha, \
  32. check_random_perspective, check_random_erasing, check_cutout, check_linear_transform, check_random_affine, \
  33. check_mix_up, check_positive_degrees, check_uniform_augment_py, check_auto_contrast, check_rgb_to_bgr, \
  34. check_adjust_gamma
  35. from .utils import Inter, Border
  36. from .py_transforms_util import is_pil
  37. DE_PY_INTER_MODE = {Inter.NEAREST: Image.NEAREST,
  38. Inter.ANTIALIAS: Image.ANTIALIAS,
  39. Inter.LINEAR: Image.LINEAR,
  40. Inter.CUBIC: Image.CUBIC}
  41. DE_PY_BORDER_TYPE = {Border.CONSTANT: 'constant',
  42. Border.EDGE: 'edge',
  43. Border.REFLECT: 'reflect',
  44. Border.SYMMETRIC: 'symmetric'}
  45. def not_random(function):
  46. """
  47. Specify the function as "not random", i.e., it produces deterministic result.
  48. A Python function can only be cached after it is specified as "not random".
  49. """
  50. function.random = False
  51. return function
  52. class ToTensor(py_transforms.PyTensorOperation):
  53. """
  54. Convert the input PIL Image or numpy.ndarray of shape (H, W, C) in the range [0, 255] to numpy.ndarray of
  55. shape (C, H, W) in the range [0.0, 1.0] with the desired dtype.
  56. Note:
  57. The values in the input image will be rescaled from [0, 255] to [0.0, 1.0].
  58. The dtype will be cast to `output_type`.
  59. The number of channels remains the same.
  60. Args:
  61. output_type (numpy.dtype, optional): The dtype of the numpy.ndarray output (default=np.float32).
  62. Raises:
  63. TypeError: If the input is not PIL Image or numpy.ndarray.
  64. TypeError: If the dimension of input is not 2 or 3.
  65. Examples:
  66. >>> from mindspore.dataset.transforms.py_transforms import Compose
  67. >>> # create a list of transformations to be applied to the "image" column of each data row
  68. >>> transforms_list = Compose([py_vision.Decode(),
  69. ... py_vision.RandomHorizontalFlip(0.5),
  70. ... py_vision.ToTensor()])
  71. >>> # apply the transform to dataset through map function
  72. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  73. ... input_columns="image")
  74. """
  75. def __init__(self, output_type=np.float32):
  76. self.output_type = output_type
  77. self.random = False
  78. def __call__(self, img):
  79. """
  80. Call method.
  81. Args:
  82. img (Union[PIL Image, numpy.ndarray]): PIL Image or numpy.ndarray to be type converted.
  83. Returns:
  84. numpy.ndarray, converted numpy.ndarray with desired type.
  85. """
  86. return util.to_tensor(img, self.output_type)
  87. class ToType(py_transforms.PyTensorOperation):
  88. """
  89. Convert the input numpy.ndarray image to the desired dtype.
  90. Args:
  91. output_type (numpy.dtype): The dtype of the numpy.ndarray output, e.g. numpy.float32.
  92. Raises:
  93. TypeError: If the input is not numpy.ndarray.
  94. Examples:
  95. >>> from mindspore.dataset.transforms.py_transforms import Compose
  96. >>> import numpy as np
  97. >>> transforms_list =Compose([py_vision.Decode(),
  98. ... py_vision.RandomHorizontalFlip(0.5),
  99. ... py_vision.ToTensor(),
  100. ... py_vision.ToType(np.float32)])
  101. >>> # apply the transform to dataset through map function
  102. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  103. ... input_columns="image")
  104. """
  105. def __init__(self, output_type):
  106. self.output_type = output_type
  107. self.random = False
  108. def __call__(self, img):
  109. """
  110. Call method.
  111. Args:
  112. img (numpy.ndarray): numpy.ndarray to be dtype converted.
  113. Returns:
  114. numpy.ndarray, converted numpy.ndarray with desired dtype.
  115. """
  116. return util.to_type(img, self.output_type)
  117. class HWC2CHW(py_transforms.PyTensorOperation):
  118. """
  119. Transpose the input numpy.ndarray image of shape (H, W, C) to (C, H, W).
  120. Raises:
  121. TypeError: If the input is not numpy.ndarray.
  122. TypeError: If the dimension of input is not 3.
  123. Examples:
  124. >>> from mindspore.dataset.transforms.py_transforms import Compose
  125. >>> transforms_list = Compose([py_vision.Decode(),
  126. ... py_vision.HWC2CHW()])
  127. >>> # apply the transform to dataset through map function
  128. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  129. ... input_columns="image")
  130. """
  131. def __init__(self):
  132. self.random = False
  133. def __call__(self, img):
  134. """
  135. Call method.
  136. Args:
  137. img (numpy.ndarray): numpy.ndarray of shape (H, W, C) to be transposed.
  138. Returns:
  139. numpy.ndarray, transposed numpy.ndarray of shape (C, H, W).
  140. """
  141. return util.hwc_to_chw(img)
  142. class ToPIL(py_transforms.PyTensorOperation):
  143. """
  144. Convert the input decoded numpy.ndarray image to PIL Image.
  145. Note:
  146. The conversion mode will be determined from type according to `PIL.Image.fromarray`.
  147. Raises:
  148. TypeError: If the input is not numpy.ndarray or PIL Image.
  149. Examples:
  150. >>> # data is already decoded, but not in PIL Image format
  151. >>> from mindspore.dataset.transforms.py_transforms import Compose
  152. >>> transforms_list = Compose([py_vision.ToPIL(),
  153. ... py_vision.RandomHorizontalFlip(0.5),
  154. ... py_vision.ToTensor()])
  155. >>> # apply the transform to dataset through map function
  156. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  157. ... input_columns="image")
  158. """
  159. def __init__(self):
  160. self.random = False
  161. def __call__(self, img):
  162. """
  163. Call method.
  164. Args:
  165. img (numpy.ndarray): Decoded numpy.ndarray image to be converted to PIL Image.
  166. Returns:
  167. PIL Image, converted PIL Image.
  168. """
  169. return util.to_pil(img)
  170. class Decode(py_transforms.PyTensorOperation):
  171. """
  172. Decode the input raw image to PIL Image format in RGB mode.
  173. Raises:
  174. ValueError: If the input is not raw data.
  175. ValueError: If the input image is already decoded.
  176. Examples:
  177. >>> from mindspore.dataset.transforms.py_transforms import Compose
  178. >>> transforms_list = Compose([py_vision.Decode(),
  179. ... py_vision.RandomHorizontalFlip(0.5),
  180. ... py_vision.ToTensor()])
  181. >>> # apply the transform to dataset through map function
  182. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  183. ... input_columns="image")
  184. """
  185. def __init__(self):
  186. self.random = False
  187. def __call__(self, img):
  188. """
  189. Call method.
  190. Args:
  191. img (Bytes-like Object): Raw image data to be decoded.
  192. Returns:
  193. PIL Image, decoded PIL Image in RGB mode.
  194. """
  195. return util.decode(img)
  196. class Normalize(py_transforms.PyTensorOperation):
  197. r"""
  198. Normalize the input numpy.ndarray image of shape (C, H, W) with the specified mean and standard deviation.
  199. .. math::
  200. output_{c} = \frac{input_{c} - mean_{c}}{std_{c}}
  201. Note:
  202. The values of the input image need to be in the range [0.0, 1.0]. If not so, call `ToTensor` first.
  203. Args:
  204. mean (Union[float, sequence]): list or tuple of mean values for each channel, arranged in channel order. The
  205. values must be in the range [0.0, 1.0].
  206. If a single float is provided, it will be filled to the same length as the channel.
  207. std (Union[float, sequence]): list or tuple of standard deviation values for each channel, arranged in channel
  208. order. The values must be in the range (0.0, 1.0].
  209. If a single float is provided, it will be filled to the same length as the channel.
  210. Raises:
  211. TypeError: If the input is not numpy.ndarray.
  212. TypeError: If the dimension of input is not 3.
  213. NotImplementedError: If the dtype of input is a subdtype of np.integer.
  214. ValueError: If the lengths of the mean and std are not equal.
  215. ValueError: If the length of the mean or std is neither equal to the channel length nor 1.
  216. Examples:
  217. >>> from mindspore.dataset.transforms.py_transforms import Compose
  218. >>> transforms_list = Compose([py_vision.Decode(),
  219. ... py_vision.RandomHorizontalFlip(0.5),
  220. ... py_vision.ToTensor(),
  221. ... py_vision.Normalize((0.491, 0.482, 0.447), (0.247, 0.243, 0.262))])
  222. >>> # apply the transform to dataset through map function
  223. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  224. ... input_columns="image")
  225. """
  226. @check_normalize_py
  227. def __init__(self, mean, std):
  228. self.mean = mean
  229. self.std = std
  230. self.random = False
  231. def __call__(self, img):
  232. """
  233. Call method.
  234. Args:
  235. img (numpy.ndarray): numpy.ndarray to be normalized.
  236. Returns:
  237. numpy.ndarray, normalized numpy.ndarray.
  238. """
  239. return util.normalize(img, self.mean, self.std)
  240. class NormalizePad(py_transforms.PyTensorOperation):
  241. r"""
  242. Normalize the input numpy.ndarray image of shape (C, H, W) with the specified mean and standard deviation,
  243. then pad an extra channel filled with zeros.
  244. .. math::
  245. output_{c} = \begin{cases}
  246. \frac{input_{c} - mean_{c}}{std_{c}}, & \text{if} \quad 0 \le c < 3 \text{;}\\
  247. 0, & \text{if} \quad c = 3 \text{.}
  248. \end{cases}
  249. Note:
  250. The values of the input image need to be in the range [0.0, 1.0]. If not so, call `ToTensor` first.
  251. Args:
  252. mean (Union[float, sequence]): list or tuple of mean values for each channel, arranged in channel order. The
  253. values must be in the range [0.0, 1.0].
  254. If a single float is provided, it will be filled to the same length as the channel.
  255. std (Union[float, sequence]): list or tuple of standard deviation values for each channel, arranged in channel
  256. order. The values must be in the range (0.0, 1.0].
  257. If a single float is provided, it will be filled to the same length as the channel.
  258. dtype (str): The dtype of the numpy.ndarray output when `pad_channel` is set True. Only "float32" and "float16"
  259. are supported (default="float32").
  260. Raises:
  261. TypeError: If the input is not numpy.ndarray.
  262. TypeError: If the dimension of input is not 3.
  263. NotImplementedError: If the dtype of input is a subdtype of np.integer.
  264. ValueError: If the length of the mean and std are not equal.
  265. ValueError: If the length of the mean or std is neither equal to the channel length nor 1.
  266. Examples:
  267. >>> from mindspore.dataset.transforms.py_transforms import Compose
  268. >>> transforms_list = Compose([py_vision.Decode(),
  269. ... py_vision.RandomHorizontalFlip(0.5),
  270. ... py_vision.ToTensor(),
  271. ... py_vision.NormalizePad((0.491, 0.482, 0.447), (0.247, 0.243, 0.262), "float32")])
  272. >>> # apply the transform to dataset through map function
  273. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  274. ... input_columns="image")
  275. """
  276. @check_normalizepad_py
  277. def __init__(self, mean, std, dtype="float32"):
  278. self.mean = mean
  279. self.std = std
  280. self.dtype = dtype
  281. self.random = False
  282. def __call__(self, img):
  283. """
  284. Call method.
  285. Args:
  286. img (numpy.ndarray): numpy.ndarray to be normalized and padded.
  287. Returns:
  288. numpy.ndarray, normalized and padded numpy.ndarray.
  289. """
  290. return util.normalize(img, self.mean, self.std, pad_channel=True, dtype=self.dtype)
  291. class RandomCrop(py_transforms.PyTensorOperation):
  292. """
  293. Crop the input PIL Image at a random location with the specified size.
  294. Args:
  295. size (Union[int, sequence]): The output size of the cropped image.
  296. If size is an integer, a square of size (size, size) is returned.
  297. If size is a sequence of length 2, it should be in shape of (height, width).
  298. padding (Union[int, sequence], optional): Padding on each border of the image (default=None).
  299. If padding is not None, pad the image before cropping.
  300. If a single number is provided, pad all borders with this value.
  301. If a sequence of length 2 is provided, pad the left/top border
  302. with the first value and right/bottom border with the second value.
  303. If a sequence of length 4 is provided, pad the left, top, right and bottom borders respectively.
  304. pad_if_needed (bool, optional): Pad the image if either side is smaller than
  305. the given output size (default=False).
  306. fill_value (Union[int, tuple], optional): Pixel fill value to pad the borders when padding_mode is
  307. Border.CONSTANT (default=0). If a tuple of length 3 is provided, it is used to fill R, G, B
  308. channels respectively.
  309. padding_mode (Border, optional): The method of padding (default=Border.CONSTANT). It can be any of
  310. [Border.CONSTANT, Border.EDGE, Border.REFLECT, Border.SYMMETRIC].
  311. - Border.CONSTANT, means to pad with given constant values.
  312. - Border.EDGE, means to pad with the last value at the edge.
  313. - Border.REFLECT, means to pad with reflection of image omitting the last value at the edge.
  314. - Border.SYMMETRIC, means to pad with reflection of image repeating the last value at the edge.
  315. Examples:
  316. >>> from mindspore.dataset.transforms.py_transforms import Compose
  317. >>> transforms_list = Compose([py_vision.Decode(),
  318. ... py_vision.RandomCrop(224),
  319. ... py_vision.ToTensor()])
  320. >>> # apply the transform to dataset through map function
  321. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  322. ... input_columns="image")
  323. """
  324. @check_random_crop
  325. def __init__(self, size, padding=None, pad_if_needed=False, fill_value=0, padding_mode=Border.CONSTANT):
  326. if padding is None:
  327. padding = (0, 0, 0, 0)
  328. else:
  329. padding = parse_padding(padding)
  330. self.size = size
  331. self.padding = padding
  332. self.pad_if_needed = pad_if_needed
  333. self.fill_value = fill_value
  334. self.padding_mode = DE_PY_BORDER_TYPE[padding_mode]
  335. def __call__(self, img):
  336. """
  337. Call method.
  338. Args:
  339. img (PIL Image): Image to be randomly cropped.
  340. Returns:
  341. PIL Image, cropped image.
  342. """
  343. return util.random_crop(img, self.size, self.padding, self.pad_if_needed,
  344. self.fill_value, self.padding_mode)
  345. class RandomHorizontalFlip(py_transforms.PyTensorOperation):
  346. """
  347. Randomly flip the input image horizontally with a given probability.
  348. Args:
  349. prob (float, optional): Probability of the image to be horizontally flipped (default=0.5).
  350. Examples:
  351. >>> from mindspore.dataset.transforms.py_transforms import Compose
  352. >>> transforms_list = Compose([py_vision.Decode(),
  353. ... py_vision.RandomHorizontalFlip(0.5),
  354. ... py_vision.ToTensor()])
  355. >>> # apply the transform to dataset through map function
  356. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  357. ... input_columns="image")
  358. """
  359. @check_prob
  360. def __init__(self, prob=0.5):
  361. self.prob = prob
  362. def __call__(self, img):
  363. """
  364. Call method.
  365. Args:
  366. img (PIL Image): Image to be horizontally flipped.
  367. Returns:
  368. PIL Image, randomly horizontally flipped image.
  369. """
  370. return util.random_horizontal_flip(img, self.prob)
  371. class RandomVerticalFlip(py_transforms.PyTensorOperation):
  372. """
  373. Randomly flip the input image vertically with a given probability.
  374. Args:
  375. prob (float, optional): Probability of the image to be vertically flipped (default=0.5).
  376. Examples:
  377. >>> from mindspore.dataset.transforms.py_transforms import Compose
  378. >>> transforms_list = Compose([py_vision.Decode(),
  379. ... py_vision.RandomVerticalFlip(0.5),
  380. ... py_vision.ToTensor()])
  381. >>> # apply the transform to dataset through map function
  382. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  383. ... input_columns="image")
  384. """
  385. @check_prob
  386. def __init__(self, prob=0.5):
  387. self.prob = prob
  388. def __call__(self, img):
  389. """
  390. Call method.
  391. Args:
  392. img (PIL Image): Image to be vertically flipped.
  393. Returns:
  394. PIL Image, randomly vertically flipped image.
  395. """
  396. return util.random_vertical_flip(img, self.prob)
  397. class Resize(py_transforms.PyTensorOperation):
  398. """
  399. Resize the input PIL Image to the given size.
  400. Args:
  401. size (Union[int, sequence]): The output size of the image.
  402. If size is an integer, the smaller edge of the image will be resized to this
  403. value, keeping the image aspect ratio the same.
  404. If size is a sequence of length 2, it should be in shape of (height, width).
  405. interpolation (Inter, optional): Image interpolation mode (default=Inter.BILINEAR).
  406. It can be any of [Inter.NEAREST, Inter.ANTIALIAS, Inter.BILINEAR, Inter.BICUBIC].
  407. - Inter.NEAREST, nearest-neighbor interpolation.
  408. - Inter.ANTIALIAS, antialias interpolation.
  409. - Inter.BILINEAR, bilinear interpolation.
  410. - Inter.BICUBIC, bicubic interpolation.
  411. Examples:
  412. >>> from mindspore.dataset.transforms.py_transforms import Compose
  413. >>> transforms_list = Compose([py_vision.Decode(),
  414. ... py_vision.Resize(256),
  415. ... py_vision.ToTensor()])
  416. >>> # apply the transform to dataset through map function
  417. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  418. ... input_columns="image")
  419. """
  420. @check_resize_interpolation
  421. def __init__(self, size, interpolation=Inter.BILINEAR):
  422. self.size = size
  423. self.interpolation = DE_PY_INTER_MODE[interpolation]
  424. self.random = False
  425. def __call__(self, img):
  426. """
  427. Call method.
  428. Args:
  429. img (PIL Image): Image to be resized.
  430. Returns:
  431. PIL Image, resized image.
  432. """
  433. return util.resize(img, self.size, self.interpolation)
  434. class RandomResizedCrop(py_transforms.PyTensorOperation):
  435. """
  436. Randomly crop the image and resize it to a given size.
  437. Args:
  438. size (Union[int, sequence]): The size of the output image.
  439. If size is an integer, a square of size (size, size) is returned.
  440. If size is a sequence of length 2, it should be in shape of (height, width).
  441. scale (Union[list, tuple], optional): Respective size range of the original image to be cropped
  442. in shape of (min, max) (default=(0.08, 1.0)).
  443. ratio (Union[list, tuple], optional): Aspect ratio range to be cropped
  444. in shape of (min, max) (default=(3./4., 4./3.)).
  445. interpolation (Inter, optional): Image interpolation mode (default=Inter.BILINEAR).
  446. It can be any of [Inter.NEAREST, Inter.ANTIALIAS, Inter.BILINEAR, Inter.BICUBIC].
  447. - Inter.NEAREST, nearest-neighbor interpolation.
  448. - Inter.ANTIALIAS, antialias interpolation.
  449. - Inter.BILINEAR, bilinear interpolation.
  450. - Inter.BICUBIC, bicubic interpolation.
  451. max_attempts (int, optional): The maximum number of attempts to propose a valid
  452. crop area (default=10). If exceeded, fall back to use center crop instead.
  453. Examples:
  454. >>> from mindspore.dataset.transforms.py_transforms import Compose
  455. >>> transforms_list = Compose([py_vision.Decode(),
  456. ... py_vision.RandomResizedCrop(224),
  457. ... py_vision.ToTensor()])
  458. >>> # apply the transform to dataset through map function
  459. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  460. ... input_columns="image")
  461. """
  462. @check_random_resize_crop
  463. def __init__(self, size, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.),
  464. interpolation=Inter.BILINEAR, max_attempts=10):
  465. self.size = size
  466. self.scale = scale
  467. self.ratio = ratio
  468. self.interpolation = DE_PY_INTER_MODE[interpolation]
  469. self.max_attempts = max_attempts
  470. def __call__(self, img):
  471. """
  472. Call method.
  473. Args:
  474. img (PIL Image): Image to be randomly cropped and resized.
  475. Returns:
  476. PIL Image, randomly cropped and resized image.
  477. """
  478. return util.random_resize_crop(img, self.size, self.scale, self.ratio,
  479. self.interpolation, self.max_attempts)
  480. class CenterCrop(py_transforms.PyTensorOperation):
  481. """
  482. Crop the central region of the input PIL Image with the given size.
  483. Args:
  484. size (Union[int, sequence]): The output size of the cropped image.
  485. If size is an integer, a square of size (size, size) is returned.
  486. If size is a sequence of length 2, it should be in shape of (height, width).
  487. Examples:
  488. >>> from mindspore.dataset.transforms.py_transforms import Compose
  489. >>> transforms_list = Compose([py_vision.Decode(),
  490. ... py_vision.CenterCrop(64),
  491. ... py_vision.ToTensor()])
  492. >>> # apply the transform to dataset through map function
  493. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  494. ... input_columns="image")
  495. """
  496. @check_center_crop
  497. def __init__(self, size):
  498. self.size = size
  499. self.random = False
  500. def __call__(self, img):
  501. """
  502. Call method.
  503. Args:
  504. img (PIL Image): Image to be center cropped.
  505. Returns:
  506. PIL Image, cropped image.
  507. """
  508. return util.center_crop(img, self.size)
  509. class RandomColorAdjust(py_transforms.PyTensorOperation):
  510. """
  511. Randomly adjust the brightness, contrast, saturation, and hue of the input PIL Image.
  512. Args:
  513. brightness (Union[float, tuple], optional): Brightness adjustment factor,
  514. which must be non negative (default=(1, 1)).
  515. If brightness is a float, the factor is uniformly chosen in range of [max(0, 1-brightness), 1+brightness].
  516. If brightness is a sequence of length 2, it should be in shape of [min, max].
  517. contrast (Union[float, tuple], optional): Contrast adjustment factor,
  518. which must be non negative (default=(1, 1)).
  519. If contrast is a float, the factor is uniformly chosen in range of [max(0, 1-contrast), 1+contrast].
  520. If contrast is a sequence of length 2, it should be in shape of [min, max].
  521. saturation (Union[float, tuple], optional): Saturation adjustment factor,
  522. which must be non negative(default=(1, 1)).
  523. If saturation is a float, the factor is uniformly chosen in range of [max(0, 1-saturation), 1+saturation].
  524. If saturation is a sequence of length 2, it should be in shape of [min, max].
  525. hue (Union[float, tuple], optional): Hue adjustment factor (default=(0, 0)).
  526. If hue is a float, the range will be [-hue, hue], where 0 <= hue <= 0.5.
  527. If hue is a sequence of length 2, it should be in shape of [min, max], where -0.5 <= min <= max <= 0.5.
  528. Examples:
  529. >>> from mindspore.dataset.transforms.py_transforms import Compose
  530. >>> transforms_list = Compose([py_vision.Decode(),
  531. ... py_vision.RandomColorAdjust(0.4, 0.4, 0.4, 0.1),
  532. ... py_vision.ToTensor()])
  533. >>> # apply the transform to dataset through map function
  534. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  535. ... input_columns="image")
  536. """
  537. @check_random_color_adjust
  538. def __init__(self, brightness=(1, 1), contrast=(1, 1), saturation=(1, 1), hue=(0, 0)):
  539. self.brightness = brightness
  540. self.contrast = contrast
  541. self.saturation = saturation
  542. self.hue = hue
  543. def __call__(self, img):
  544. """
  545. Call method.
  546. Args:
  547. img (PIL image): Image to be randomly color adjusted.
  548. Returns:
  549. PIL Image, randomly color adjusted image.
  550. """
  551. return util.random_color_adjust(img, self.brightness, self.contrast, self.saturation, self.hue)
  552. class RandomRotation(py_transforms.PyTensorOperation):
  553. """
  554. Rotate the input PIL Image by a random angle.
  555. Note:
  556. See https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.rotate.
  557. Args:
  558. degrees (Union[int, float, sequence]): Range of random rotation degrees.
  559. If `degrees` is a number, the range will be converted to (-degrees, degrees).
  560. If `degrees` is a sequence of length 2, it should be in shape of (min, max).
  561. resample (Inter, optional): An optional resampling filter (default=Inter.NEAREST).
  562. If the image is in mode of "1" or "P", it is set to Inter.NEAREST by default.
  563. It can be any of [Inter.NEAREST, Inter.ANTIALIAS, Inter.BILINEAR, Inter.BICUBIC].
  564. - Inter.NEAREST, nearest-neighbor interpolation.
  565. - Inter.ANTIALIAS, antialias interpolation.
  566. - Inter.BILINEAR, bilinear interpolation.
  567. - Inter.BICUBIC, bicubic interpolation.
  568. expand (bool, optional): Optional expansion flag (default=False).
  569. If set to True, expand the output image to make it large enough to hold the entire rotated image.
  570. If set to False, keep the output image the same size as the input.
  571. Note that the expand flag assumes rotation around the center and no translation.
  572. center (tuple, optional): Optional center of rotation, which must be a tuple of length 2 (default=None).
  573. Origin is the top left corner. Default None means to set the center of the image.
  574. fill_value (int or tuple, optional): Pixel fill value for the area outside the rotated image (default=0).
  575. If fill_value is a tuple of length 3, it is used to fill R, G, B channels respectively.
  576. If fill_value is an integer, it is used to fill all RGB channels.
  577. Examples:
  578. >>> from mindspore.dataset.transforms.py_transforms import Compose
  579. >>> transforms_list = Compose([py_vision.Decode(),
  580. ... py_vision.RandomRotation(30),
  581. ... py_vision.ToTensor()])
  582. >>> # apply the transform to dataset through map function
  583. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  584. ... input_columns="image")
  585. """
  586. @check_random_rotation
  587. def __init__(self, degrees, resample=Inter.NEAREST, expand=False, center=None, fill_value=0):
  588. self.degrees = degrees
  589. self.resample = DE_PY_INTER_MODE[resample]
  590. self.expand = expand
  591. self.center = center
  592. self.fill_value = fill_value
  593. def __call__(self, img):
  594. """
  595. Call method.
  596. Args:
  597. img (PIL Image): Image to be randomly rotated.
  598. Returns:
  599. PIL Image, randomly rotated image.
  600. """
  601. return util.random_rotation(img, self.degrees, self.resample, self.expand, self.center, self.fill_value)
  602. class FiveCrop(py_transforms.PyTensorOperation):
  603. """
  604. Crop the given image into one central crop and four corners.
  605. Args:
  606. size (Union[int, sequence]): The output size of the cropped images.
  607. If size is an integer, a square of size (size, size) is returned.
  608. If size is a sequence of length 2, it should be in shape of (height, width).
  609. Examples:
  610. >>> from mindspore.dataset.transforms.py_transforms import Compose
  611. >>> transforms_list = Compose([py_vision.Decode(),
  612. ... py_vision.FiveCrop(size=200),
  613. ... # 4D stack of 5 images
  614. ... lambda *images: numpy.stack([py_vision.ToTensor()(image) for image in images])])
  615. >>> # apply the transform to dataset through map function
  616. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  617. ... input_columns="image")
  618. """
  619. @check_five_crop
  620. def __init__(self, size):
  621. self.size = size
  622. self.random = False
  623. def __call__(self, img):
  624. """
  625. Call method.
  626. Args:
  627. img (PIL Image): Image to be cropped.
  628. Returns:
  629. tuple, a tuple of five PIL Image in order of top_left, top_right, bottom_left, bottom_right, center.
  630. """
  631. return util.five_crop(img, self.size)
  632. class TenCrop(py_transforms.PyTensorOperation):
  633. """
  634. Crop the given image into one central crop and four corners plus the flipped version of these.
  635. Args:
  636. size (Union[int, sequence]): The output size of the cropped images.
  637. If size is an integer, a square of size (size, size) is returned.
  638. If size is a sequence of length 2, it should be in shape of (height, width).
  639. use_vertical_flip (bool, optional): Whether to flip the image vertically,
  640. otherwise horizontally (default=False).
  641. Examples:
  642. >>> import numpy
  643. >>> from mindspore.dataset.transforms.py_transforms import Compose
  644. >>> transforms_list = Compose([py_vision.Decode(),
  645. ... py_vision.TenCrop(size=200),
  646. ... # 4D stack of 10 images
  647. ... lambda *images: numpy.stack([py_vision.ToTensor()(image) for image in images])])
  648. >>> # apply the transform to dataset through map function
  649. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  650. ... input_columns="image")
  651. """
  652. @check_ten_crop
  653. def __init__(self, size, use_vertical_flip=False):
  654. if isinstance(size, int):
  655. size = (size, size)
  656. self.size = size
  657. self.use_vertical_flip = use_vertical_flip
  658. self.random = False
  659. def __call__(self, img):
  660. """
  661. Call method.
  662. Args:
  663. img (PIL Image): Image to be cropped.
  664. Returns:
  665. tuple, a tuple of 10 PIL Image, in order of top_left, top_right, bottom_left, bottom_right, center
  666. of the original image and top_left, top_right, bottom_left, bottom_right, center of the flipped image.
  667. """
  668. return util.ten_crop(img, self.size, self.use_vertical_flip)
  669. class Grayscale(py_transforms.PyTensorOperation):
  670. """
  671. Convert the input PIL Image to grayscale.
  672. Args:
  673. num_output_channels (int): Number of channels of the output grayscale image, which can be 1 or 3 (default=1).
  674. If num_output_channels is 3, the returned image will have 3 identical RGB channels.
  675. Examples:
  676. >>> from mindspore.dataset.transforms.py_transforms import Compose
  677. >>> transforms_list = Compose([py_vision.Decode(),
  678. ... py_vision.Grayscale(3),
  679. ... py_vision.ToTensor()])
  680. >>> # apply the transform to dataset through map function
  681. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  682. ... input_columns="image")
  683. """
  684. @check_num_channels
  685. def __init__(self, num_output_channels=1):
  686. self.num_output_channels = num_output_channels
  687. self.random = False
  688. def __call__(self, img):
  689. """
  690. Call method.
  691. Args:
  692. img (PIL Image): Image to be converted to grayscale.
  693. Returns:
  694. PIL Image, converted grayscale image.
  695. """
  696. return util.grayscale(img, num_output_channels=self.num_output_channels)
  697. class RandomGrayscale(py_transforms.PyTensorOperation):
  698. """
  699. Randomly convert the input image into grayscale with a given probability.
  700. Args:
  701. prob (float, optional): Probability of the image being converted to grayscale (default=0.1).
  702. Examples:
  703. >>> from mindspore.dataset.transforms.py_transforms import Compose
  704. >>> transforms_list = Compose([py_vision.Decode(),
  705. ... py_vision.RandomGrayscale(0.3),
  706. ... py_vision.ToTensor()])
  707. >>> # apply the transform to dataset through map function
  708. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  709. ... input_columns="image")
  710. """
  711. @check_prob
  712. def __init__(self, prob=0.1):
  713. self.prob = prob
  714. def __call__(self, img):
  715. """
  716. Call method.
  717. Args:
  718. img (PIL Image): Image to be randomly converted to grayscale.
  719. Returns:
  720. PIL Image, randomly converted grayscale image, which has the same number of channels as the input image.
  721. If input image has 1 channel, the output grayscale image will have 1 channel.
  722. If input image has 3 channels, the output grayscale image will have 3 identical channels.
  723. """
  724. if img.mode == 'L':
  725. num_output_channels = 1
  726. else:
  727. num_output_channels = 3
  728. if self.prob > random.random():
  729. return util.grayscale(img, num_output_channels=num_output_channels)
  730. return img
  731. class Pad(py_transforms.PyTensorOperation):
  732. """
  733. Pad the input image on all sides with the given padding parameters.
  734. Args:
  735. padding (Union[int, sequence]): The number of pixels padded on the image borders.
  736. If a single number is provided, pad all borders with this value.
  737. If a sequence of length 2 is provided, pad the left and top with the
  738. first value and the right and bottom with the second value.
  739. If a sequence of length 4 is provided, pad the left, top, right and bottom respectively.
  740. fill_value (Union[int, tuple], optional): Pixel fill value to pad the borders,
  741. only valid when padding_mode is Border.CONSTANT (default=0).
  742. If fill_value is an integer, it is used for all RGB channels.
  743. If fill_value is a tuple of length 3, it is used to fill R, G, B channels respectively.
  744. padding_mode (Border, optional): The method of padding (default=Border.CONSTANT).
  745. It can be any of [Border.CONSTANT, Border.EDGE, Border.REFLECT, Border.SYMMETRIC].
  746. - Border.CONSTANT, pads with a constant value.
  747. - Border.EDGE, pads with the last value at the edge of the image.
  748. - Border.REFLECT, pads with reflection of the image omitting the last value on the edge.
  749. - Border.SYMMETRIC, pads with reflection of the image repeating the last value on the edge.
  750. Examples:
  751. >>> from mindspore.dataset.transforms.py_transforms import Compose
  752. >>> transforms_list = Compose([py_vision.Decode(),
  753. ... # adds 10 pixels (default black) to each border of the image
  754. ... py_vision.Pad(padding=10),
  755. ... py_vision.ToTensor()])
  756. >>> # apply the transform to dataset through map function
  757. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  758. ... input_columns="image")
  759. """
  760. @check_pad
  761. def __init__(self, padding, fill_value=0, padding_mode=Border.CONSTANT):
  762. parse_padding(padding)
  763. self.padding = padding
  764. self.fill_value = fill_value
  765. self.padding_mode = DE_PY_BORDER_TYPE[padding_mode]
  766. self.random = False
  767. def __call__(self, img):
  768. """
  769. Call method.
  770. Args:
  771. img (PIL Image): Image to be padded.
  772. Returns:
  773. PIL Image, padded image.
  774. """
  775. return util.pad(img, self.padding, self.fill_value, self.padding_mode)
  776. class RandomPerspective(py_transforms.PyTensorOperation):
  777. """
  778. Randomly apply perspective transformation to the input PIL Image with a given probability.
  779. Args:
  780. distortion_scale (float, optional): The scale of distortion, in range of [0, 1] (default=0.5).
  781. prob (float, optional): Probability of the image being applied perspective transformation (default=0.5).
  782. interpolation (Inter, optional): Image interpolation mode (default=Inter.BICUBIC).
  783. It can be any of [Inter.BILINEAR, Inter.NEAREST, Inter.BICUBIC].
  784. - Inter.BILINEAR, bilinear interpolation.
  785. - Inter.NEAREST, nearest-neighbor interpolation.
  786. - Inter.BICUBIC, bicubic interpolation.
  787. Examples:
  788. >>> from mindspore.dataset.transforms.py_transforms import Compose
  789. >>> transforms_list = Compose([py_vision.Decode(),
  790. ... py_vision.RandomPerspective(prob=0.1),
  791. ... py_vision.ToTensor()])
  792. >>> # apply the transform to dataset through map function
  793. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  794. ... input_columns="image")
  795. """
  796. @check_random_perspective
  797. def __init__(self, distortion_scale=0.5, prob=0.5, interpolation=Inter.BICUBIC):
  798. self.distortion_scale = distortion_scale
  799. self.prob = prob
  800. self.interpolation = DE_PY_INTER_MODE[interpolation]
  801. def __call__(self, img):
  802. """
  803. Call method.
  804. Args:
  805. img (PIL Image): Image to be applied randomly perspective transformation.
  806. Returns:
  807. PIL Image, image applied randomly perspective transformation.
  808. """
  809. if not is_pil(img):
  810. raise ValueError("Input image should be a Pillow image.")
  811. if self.prob > random.random():
  812. start_points, end_points = util.get_perspective_params(
  813. img, self.distortion_scale)
  814. return util.perspective(img, start_points, end_points, self.interpolation)
  815. return img
  816. class RandomErasing(py_transforms.PyTensorOperation):
  817. """
  818. Randomly erase the pixels within a random selected rectangle region with a given probability.
  819. See Zhun Zhong et al. 'Random Erasing Data Augmentation' 2017 on https://arxiv.org/pdf/1708.04896.pdf
  820. Args:
  821. prob (float, optional): Probability of the image being randomly erased (default=0.5).
  822. scale (sequence of floats, optional): Range of the relative erase area to the
  823. original image (default=(0.02, 0.33)).
  824. ratio (sequence, optional): Range of aspect ratio of the erased area (default=(0.3, 3.3)).
  825. value (Union[int, sequence, str]): Erasing value (default=0).
  826. If value is a single integer, it is used to erase all pixels.
  827. If value is a sequence of length 3, it is used to erase R, G, B channels respectively.
  828. If value is a string of 'random', each pixel will be erased with a random value obtained
  829. from a standard normal distribution.
  830. inplace (bool, optional): Whether to apply this transformation inplace (default=False).
  831. max_attempts (int, optional): The maximum number of attempts to propose a valid
  832. area to be erased (default=10). If exceeded, return the original image.
  833. Examples:
  834. >>> from mindspore.dataset.transforms.py_transforms import Compose
  835. >>> transforms_list = Compose([py_vision.Decode(),
  836. ... py_vision.ToTensor(),
  837. ... py_vision.RandomErasing(value='random')])
  838. >>> # apply the transform to dataset through map function
  839. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  840. ... input_columns="image")
  841. """
  842. @check_random_erasing
  843. def __init__(self, prob=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False, max_attempts=10):
  844. self.prob = prob
  845. self.scale = scale
  846. self.ratio = ratio
  847. self.value = value
  848. self.inplace = inplace
  849. self.max_attempts = max_attempts
  850. def __call__(self, np_img):
  851. """
  852. Call method.
  853. Args:
  854. np_img (numpy.ndarray): image in shape of (C, H, W) to be randomly erased.
  855. Returns:
  856. numpy.ndarray, erased image.
  857. """
  858. bounded = True
  859. if self.prob > random.random():
  860. i, j, erase_h, erase_w, erase_value = util.get_erase_params(np_img, self.scale, self.ratio,
  861. self.value, bounded, self.max_attempts)
  862. return util.erase(np_img, i, j, erase_h, erase_w, erase_value, self.inplace)
  863. return np_img
  864. class Cutout(py_transforms.PyTensorOperation):
  865. """
  866. Randomly apply a given number of square patches of zeros to a location within the input
  867. numpy.ndarray image of shape (C, H, W).
  868. See Terrance DeVries and Graham W. Taylor 'Improved Regularization of Convolutional Neural Networks with Cutout'
  869. 2017 on https://arxiv.org/pdf/1708.04552.pdf
  870. Args:
  871. length (int): The side length of each square patch.
  872. num_patches (int, optional): Number of patches to be applied to the image (default=1).
  873. Examples:
  874. >>> from mindspore.dataset.transforms.py_transforms import Compose
  875. >>> transforms_list = Compose([py_vision.Decode(),
  876. ... py_vision.ToTensor(),
  877. ... py_vision.Cutout(80)])
  878. >>> # apply the transform to dataset through map function
  879. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  880. ... input_columns="image")
  881. """
  882. @check_cutout
  883. def __init__(self, length, num_patches=1):
  884. self.length = length
  885. self.num_patches = num_patches
  886. self.random = False
  887. def __call__(self, np_img):
  888. """
  889. Call method.
  890. Args:
  891. np_img (numpy.ndarray): Image in shape of (C, H, W) to be cut out.
  892. Returns:
  893. numpy.ndarray, image cut out.
  894. """
  895. if not isinstance(np_img, np.ndarray):
  896. raise TypeError(
  897. "img should be NumPy array. Got {}.".format(type(np_img)))
  898. if np_img.ndim != 3:
  899. raise TypeError(
  900. 'img dimension should be 3. Got {}.'.format(np_img.ndim))
  901. _, image_h, image_w = np_img.shape
  902. scale = (self.length * self.length) / (image_h * image_w)
  903. bounded = False
  904. for _ in range(self.num_patches):
  905. i, j, erase_h, erase_w, erase_value = util.get_erase_params(np_img, (scale, scale), (1, 1), 0, bounded,
  906. 1)
  907. np_img = util.erase(np_img, i, j, erase_h, erase_w, erase_value)
  908. return np_img
  909. class LinearTransformation(py_transforms.PyTensorOperation):
  910. r"""
  911. Transform the input numpy.ndarray image with a given square transformation matrix and a mean vector.
  912. It will first flatten the input image and subtract the mean vector from it, then compute the dot
  913. product with the transformation matrix, finally reshape it back to its original shape.
  914. Args:
  915. transformation_matrix (numpy.ndarray): A square transformation matrix in shape of (D, D), where
  916. :math:`D = C \times H \times W`.
  917. mean_vector (numpy.ndarray): A mean vector in shape of (D,), where :math:`D = C \times H \times W`.
  918. Examples:
  919. >>> from mindspore.dataset.transforms.py_transforms import Compose
  920. >>> import numpy as np
  921. >>> height, width = 32, 32
  922. >>> dim = 3 * height * width
  923. >>> transformation_matrix = np.ones([dim, dim])
  924. >>> mean_vector = np.zeros(dim)
  925. >>> transforms_list = Compose([py_vision.Decode(),
  926. ... py_vision.Resize((height,width)),
  927. ... py_vision.ToTensor(),
  928. ... py_vision.LinearTransformation(transformation_matrix, mean_vector)])
  929. >>> # apply the transform to dataset through map function
  930. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  931. ... input_columns="image")
  932. """
  933. @check_linear_transform
  934. def __init__(self, transformation_matrix, mean_vector):
  935. self.transformation_matrix = transformation_matrix
  936. self.mean_vector = mean_vector
  937. self.random = False
  938. def __call__(self, np_img):
  939. """
  940. Call method.
  941. Args:
  942. np_img (numpy.ndarray): Image in shape of (C, H, W) to be linearly transformed.
  943. Returns:
  944. numpy.ndarray, linearly transformed image.
  945. """
  946. return util.linear_transform(np_img, self.transformation_matrix, self.mean_vector)
  947. class RandomAffine(py_transforms.PyTensorOperation):
  948. """
  949. Apply random affine transformation to the input PIL Image.
  950. Args:
  951. degrees (Union[int, float, sequence]): Range of degrees to select from.
  952. If `degrees` is a number, the range will be (-degrees, degrees).
  953. If `degrees` is a sequence, it should be in shape of (min, max).
  954. translate (sequence, optional): Maximum absolute fraction sequence in shape of (tx, ty)
  955. for horizontal and vertical translations. The horizontal and vertical shifts are randomly
  956. selected in the range (-tx * width, tx * width) and (-ty * height, ty * height) respectively.
  957. (default=None, no translation will be applied).
  958. scale (sequence, optional): Scaling factor interval (default=None, keep original scale).
  959. shear (Union[int, float, sequence], optional): Range of shear factor to select from.
  960. If shear is an integer, a shear parallel to the X axis in the range (-shear, shear) will be applied.
  961. If shear is a sequence of length 2, a shear parallel to the X axis in the range (shear[0], shear[1])
  962. will be applied.
  963. If shear is a sequence of length 4, a shear parallel to the X axis in the range (shear[0], shear[1])
  964. and a shear parallel to the Y axis in the range (shear[2], shear[3]) will be applied.
  965. (default=None, no shear will be applied).
  966. resample (Inter, optional): An optional resampling filter (default=Inter.NEAREST).
  967. If the PIL Image is in mode of "1" or "P", it is set to Inter.NEAREST by default.
  968. It can be any of [Inter.BILINEAR, Inter.NEAREST, Inter.BICUBIC].
  969. - Inter.BILINEAR, bilinear interpolation.
  970. - Inter.NEAREST, nearest-neighbor interpolation.
  971. - Inter.BICUBIC, bicubic interpolation.
  972. fill_value (Union[int, tuple], optional): Pixel fill value for the area outside the
  973. transformed image (default=0).
  974. If fill_value is an integer, it is used for all RGB channels.
  975. If fill_value is a tuple of length 3, it is used to fill R, G, B channels respectively.
  976. Only supported with Pillow version > 5.0.0.
  977. Raises:
  978. ValueError: If `degrees` is negative.
  979. ValueError: If translation is not between 0 and 1.
  980. ValueError: If scale is not positive.
  981. ValueError: If shear is a non positive number.
  982. TypeError: If `degrees` is not a number or a sequence of length 2.
  983. TypeError: If translate is defined but not a sequence of length 2.
  984. TypeError: If scale is not a sequence of length 2.
  985. TypeError: If shear is not a sequence of length 2 or 4.
  986. TypeError: If fill_value is not an integer or a tuple of length 3.
  987. Examples:
  988. >>> from mindspore.dataset.transforms.py_transforms import Compose
  989. >>> transforms_list = Compose([py_vision.Decode(),
  990. ... py_vision.RandomAffine(degrees=15, translate=(0.1, 0.1), scale=(0.9, 1.1)),
  991. ... py_vision.ToTensor()])
  992. >>> # apply the transform to dataset through map function
  993. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  994. ... input_columns="image")
  995. """
  996. @check_random_affine
  997. def __init__(self, degrees, translate=None, scale=None, shear=None, resample=Inter.NEAREST, fill_value=0):
  998. if shear is not None:
  999. if isinstance(shear, numbers.Number):
  1000. shear = (-1 * shear, shear)
  1001. else:
  1002. if len(shear) == 2:
  1003. shear = [shear[0], shear[1], 0., 0.]
  1004. elif len(shear) == 4:
  1005. shear = [s for s in shear]
  1006. if isinstance(degrees, numbers.Number):
  1007. degrees = (-degrees, degrees)
  1008. self.degrees = degrees
  1009. self.translate = translate
  1010. self.scale_ranges = scale
  1011. self.shear = shear
  1012. self.resample = DE_PY_INTER_MODE[resample]
  1013. self.fill_value = fill_value
  1014. def __call__(self, img):
  1015. """
  1016. Call method.
  1017. Args:
  1018. img (PIL Image): Image to be randomly affine transformed.
  1019. Returns:
  1020. PIL Image, randomly affine transformed image.
  1021. """
  1022. return util.random_affine(img,
  1023. self.degrees,
  1024. self.translate,
  1025. self.scale_ranges,
  1026. self.shear,
  1027. self.resample,
  1028. self.fill_value)
  1029. class MixUp(py_transforms.PyTensorOperation):
  1030. """
  1031. Randomly mix up a batch of images together with its labels. Each image will be multiplied by a random
  1032. weight lambda generated from the beta distribution and then added to another image multiplied by 1 - lambda.
  1033. The same transformation will be applied to their labels with the same value of lambda. Make sure that the
  1034. labels are one hot encoded in advance.
  1035. Args:
  1036. batch_size (int): The number of images in a batch.
  1037. alpha (float): The alpha and beta parameter in the beta distribution.
  1038. is_single (bool, optional): If True, it will randomly mix up [img(0), ..., img(n-1), img(n)] with
  1039. [img1, ..., img(n), img0] in each batch. Otherwise, it will randomly mix up images with the
  1040. output of mixing of previous batch of images (Default=True).
  1041. Examples:
  1042. >>> # Setup multi-batch mixup transformation
  1043. >>> transform = [py_vision.MixUp(batch_size=16, alpha=0.2, is_single=False)]
  1044. >>> # Apply the transform to the dataset through dataset.map()
  1045. >>> image_folder_dataset = image_folder_dataset.map(input_columns="image",
  1046. ... operations=transform)
  1047. """
  1048. @check_mix_up
  1049. def __init__(self, batch_size, alpha, is_single=True):
  1050. self.image = 0
  1051. self.label = 0
  1052. self.is_first = True
  1053. self.batch_size = batch_size
  1054. self.alpha = alpha
  1055. self.is_single = is_single
  1056. self.random = False
  1057. def __call__(self, image, label):
  1058. """
  1059. Call method.
  1060. Args:
  1061. image (numpy.ndarray): Images to be mixed up.
  1062. label (numpy.ndarray): Labels to be mixed up.
  1063. Returns:
  1064. numpy.ndarray, images after mixing up.
  1065. numpy.ndarray, labels after mixing up.
  1066. """
  1067. if self.is_single:
  1068. return util.mix_up_single(self.batch_size, image, label, self.alpha)
  1069. return util.mix_up_muti(self, self.batch_size, image, label, self.alpha)
  1070. class RgbToBgr(py_transforms.PyTensorOperation):
  1071. """
  1072. Convert one or more numpy.ndarray images from RGB to BGR.
  1073. Args:
  1074. is_hwc (bool): Whether the image is in shape of (H, W, C) or (N, H, W, C), otherwise
  1075. in shape of (C, H, W) or (N, C, H, W) (default=False).
  1076. Examples:
  1077. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1078. >>> transforms_list = Compose([py_vision.Decode(),
  1079. ... py_vision.CenterCrop(20),
  1080. ... py_vision.ToTensor(),
  1081. ... py_vision.RgbToBgr()])
  1082. >>> # apply the transform to dataset through map function
  1083. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1084. ... input_columns="image")
  1085. """
  1086. @check_rgb_to_bgr
  1087. def __init__(self, is_hwc=False):
  1088. self.is_hwc = is_hwc
  1089. self.random = False
  1090. def __call__(self, rgb_imgs):
  1091. """
  1092. Call method.
  1093. Args:
  1094. rgb_imgs (numpy.ndarray): RGB images to be converted.
  1095. Returns:
  1096. numpy.ndarray, converted BGR images.
  1097. """
  1098. return util.rgb_to_bgrs(rgb_imgs, self.is_hwc)
  1099. class RgbToHsv(py_transforms.PyTensorOperation):
  1100. """
  1101. Convert one or more numpy.ndarray images from RGB to HSV.
  1102. Args:
  1103. is_hwc (bool): Whether the image is in shape of (H, W, C) or (N, H, W, C), otherwise
  1104. in shape of (C, H, W) or (N, C, H, W) (default=False).
  1105. Examples:
  1106. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1107. >>> transforms_list = Compose([py_vision.Decode(),
  1108. ... py_vision.CenterCrop(20),
  1109. ... py_vision.ToTensor(),
  1110. ... py_vision.RgbToHsv()])
  1111. >>> # apply the transform to dataset through map function
  1112. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1113. ... input_columns="image")
  1114. """
  1115. @check_rgb_to_hsv
  1116. def __init__(self, is_hwc=False):
  1117. self.is_hwc = is_hwc
  1118. self.random = False
  1119. def __call__(self, rgb_imgs):
  1120. """
  1121. Call method.
  1122. Args:
  1123. rgb_imgs (numpy.ndarray): RGB images to be converted.
  1124. Returns:
  1125. numpy.ndarray, converted HSV images.
  1126. """
  1127. return util.rgb_to_hsvs(rgb_imgs, self.is_hwc)
  1128. class HsvToRgb(py_transforms.PyTensorOperation):
  1129. """
  1130. Convert one or more numpy.ndarray images from HSV to RGB.
  1131. Args:
  1132. is_hwc (bool): Whether the image is in shape of (H, W, C) or (N, H, W, C), otherwise
  1133. in shape of (C, H, W) or (N, C, H, W) (default=False).
  1134. Examples:
  1135. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1136. >>> transforms_list = Compose([py_vision.Decode(),
  1137. ... py_vision.CenterCrop(20),
  1138. ... py_vision.ToTensor(),
  1139. ... py_vision.HsvToRgb()])
  1140. >>> # apply the transform to dataset through map function
  1141. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1142. ... input_columns="image")
  1143. """
  1144. @check_hsv_to_rgb
  1145. def __init__(self, is_hwc=False):
  1146. self.is_hwc = is_hwc
  1147. self.random = False
  1148. def __call__(self, hsv_imgs):
  1149. """
  1150. Call method.
  1151. Args:
  1152. hsv_imgs (numpy.ndarray): HSV images to be converted.
  1153. Returns:
  1154. numpy.ndarray, converted RGB images.
  1155. """
  1156. return util.hsv_to_rgbs(hsv_imgs, self.is_hwc)
  1157. class RandomColor(py_transforms.PyTensorOperation):
  1158. """
  1159. Adjust the color balance of the input PIL Image by a random degree.
  1160. Args:
  1161. degrees (sequence): Range of color adjustment degree to be randomly chosen from,
  1162. which should be in shape of (min, max) (default=(0.1,1.9)).
  1163. Examples:
  1164. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1165. >>> transforms_list = Compose([py_vision.Decode(),
  1166. ... py_vision.RandomColor((0.5, 2.0)),
  1167. ... py_vision.ToTensor()])
  1168. >>> # apply the transform to dataset through map function
  1169. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1170. ... input_columns="image")
  1171. """
  1172. @check_positive_degrees
  1173. def __init__(self, degrees=(0.1, 1.9)):
  1174. self.degrees = degrees
  1175. def __call__(self, img):
  1176. """
  1177. Call method.
  1178. Args:
  1179. img (PIL Image): Image to be color adjusted.
  1180. Returns:
  1181. PIL Image, color adjusted image.
  1182. """
  1183. return util.random_color(img, self.degrees)
  1184. class RandomLighting:
  1185. """
  1186. Add AlexNet-style PCA-based noise to an image.
  1187. Args:
  1188. alpha (float, optional): Intensity of the image (default=0.05).
  1189. Examples:
  1190. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1191. >>>
  1192. >>> transforms_list = Compose([py_vision.Decode(),
  1193. ... py_vision.RandomLighting(0.1),
  1194. ... py_vision.ToTensor()])
  1195. >>> # apply the transform to dataset through map function
  1196. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1197. ... input_columns="image")
  1198. """
  1199. @check_alpha
  1200. def __init__(self, alpha=0.05):
  1201. self.alpha = alpha
  1202. def __call__(self, img):
  1203. """
  1204. Call method.
  1205. Args:
  1206. img (PIL Image): Image to be added AlexNet-style PCA-based noise.
  1207. Returns:
  1208. PIL Image, image with noise added.
  1209. """
  1210. return util.random_lighting(img, self.alpha)
  1211. class RandomSharpness(py_transforms.PyTensorOperation):
  1212. """
  1213. Adjust the sharpness of the input PIL Image by a random degree.
  1214. Args:
  1215. degrees (sequence): Range of sharpness adjustment degree to be randomly chosen from, which
  1216. should be in shape of (min, max) (default=(0.1,1.9)).
  1217. Degree of 0.0 gives a blurred image, degree of 1.0 gives the original image,
  1218. and degree of 2.0 increases the sharpness by a factor of 2.
  1219. Examples:
  1220. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1221. >>> transforms_list = Compose([py_vision.Decode(),
  1222. ... py_vision.RandomSharpness((0.5, 1.5)),
  1223. ... py_vision.ToTensor()])
  1224. >>> # apply the transform to dataset through map function
  1225. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1226. ... input_columns="image")
  1227. """
  1228. @check_positive_degrees
  1229. def __init__(self, degrees=(0.1, 1.9)):
  1230. self.degrees = degrees
  1231. def __call__(self, img):
  1232. """
  1233. Call method.
  1234. Args:
  1235. img (PIL Image): Image to be sharpness adjusted.
  1236. Returns:
  1237. PIL Image, sharpness adjusted image.
  1238. """
  1239. return util.random_sharpness(img, self.degrees)
  1240. class AdjustGamma(py_transforms.PyTensorOperation):
  1241. """
  1242. Perform gamma correction on the input PIL Image.
  1243. Args:
  1244. gamma (float): Gamma parameter in the correction equation, which must be non negative.
  1245. gain (float, optional): The constant multiplier (default=1.0).
  1246. Examples:
  1247. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1248. >>> transforms_list = Compose([py_vision.Decode(),
  1249. ... py_vision.AdjustGamma(gamma=10.0),
  1250. ... py_vision.ToTensor()])
  1251. >>> # apply the transform to dataset through map function
  1252. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1253. ... input_columns="image")
  1254. """
  1255. @check_adjust_gamma
  1256. def __init__(self, gamma, gain=1.0):
  1257. self.gamma = gamma
  1258. self.gain = gain
  1259. self.random = False
  1260. def __call__(self, img):
  1261. """
  1262. Call method.
  1263. Args:
  1264. img (PIL Image): Image to be gamma adjusted.
  1265. Returns:
  1266. PIL Image, gamma adjusted image.
  1267. """
  1268. return util.adjust_gamma(img, self.gamma, self.gain)
  1269. class AutoContrast(py_transforms.PyTensorOperation):
  1270. """
  1271. Automatically maximize the contrast of the input PIL Image.
  1272. Args:
  1273. cutoff (float, optional): Percent of pixels to be cut off from the histogram,
  1274. which must be in range of [0.0, 50.0) (default=0.0).
  1275. ignore (Union[int, sequence], optional): Pixel values to be ignored (default=None).
  1276. Examples:
  1277. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1278. >>> transforms_list = Compose([py_vision.Decode(),
  1279. ... py_vision.AutoContrast(),
  1280. ... py_vision.ToTensor()])
  1281. >>> # apply the transform to dataset through map function
  1282. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1283. ... input_columns="image")
  1284. """
  1285. @check_auto_contrast
  1286. def __init__(self, cutoff=0.0, ignore=None):
  1287. self.cutoff = cutoff
  1288. self.ignore = ignore
  1289. self.random = False
  1290. def __call__(self, img):
  1291. """
  1292. Call method.
  1293. Args:
  1294. img (PIL Image): Image to be automatically contrasted.
  1295. Returns:
  1296. PIL Image, automatically contrasted image.
  1297. """
  1298. return util.auto_contrast(img, self.cutoff, self.ignore)
  1299. class Invert(py_transforms.PyTensorOperation):
  1300. """
  1301. Invert the colors of the input PIL Image.
  1302. Examples:
  1303. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1304. >>> transforms_list = Compose([py_vision.Decode(),
  1305. ... py_vision.Invert(),
  1306. ... py_vision.ToTensor()])
  1307. >>> # apply the transform to dataset through map function
  1308. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1309. ... input_columns="image")
  1310. """
  1311. def __init__(self):
  1312. self.random = False
  1313. def __call__(self, img):
  1314. """
  1315. Call method.
  1316. Args:
  1317. img (PIL Image): Image to be color inverted.
  1318. Returns:
  1319. PIL Image, color inverted image.
  1320. """
  1321. return util.invert_color(img)
  1322. class Equalize(py_transforms.PyTensorOperation):
  1323. """
  1324. Apply histogram equalization on the input PIL Image.
  1325. Examples:
  1326. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1327. >>> transforms_list = Compose([py_vision.Decode(),
  1328. ... py_vision.Equalize(),
  1329. ... py_vision.ToTensor()])
  1330. >>> # apply the transform to dataset through map function
  1331. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1332. ... input_columns="image")
  1333. """
  1334. def __init__(self):
  1335. self.random = False
  1336. def __call__(self, img):
  1337. """
  1338. Call method.
  1339. Args:
  1340. img (PIL Image): Image to be equalized.
  1341. Returns:
  1342. PIL Image, equalized image.
  1343. """
  1344. return util.equalize(img)
  1345. class UniformAugment(py_transforms.PyTensorOperation):
  1346. """
  1347. Uniformly select a number of transformations from a sequence and apply them
  1348. sequentially and randomly, which means that there is a chance that a chosen
  1349. transformation will not be applied.
  1350. All transformations in the sequence require the output type to be the same as
  1351. the input. Thus, the latter one can deal with the output of the previous one.
  1352. Args:
  1353. transforms (sequence): Sequence of transformations to be chosen from.
  1354. num_ops (int, optional): Number of transformations to be sequentially and randomly applied (default=2).
  1355. Examples:
  1356. >>> from mindspore.dataset.transforms.py_transforms import Compose
  1357. >>> transforms = [py_vision.CenterCrop(64),
  1358. ... py_vision.RandomColor(),
  1359. ... py_vision.RandomSharpness(),
  1360. ... py_vision.RandomRotation(30)]
  1361. >>> transforms_list = Compose([py_vision.Decode(),
  1362. ... py_vision.UniformAugment(transforms),
  1363. ... py_vision.ToTensor()])
  1364. >>> # apply the transform to dataset through map function
  1365. >>> image_folder_dataset = image_folder_dataset.map(operations=transforms_list,
  1366. ... input_columns="image")
  1367. """
  1368. @check_uniform_augment_py
  1369. def __init__(self, transforms, num_ops=2):
  1370. self.transforms = transforms
  1371. self.num_ops = num_ops
  1372. self.random = False
  1373. def __call__(self, img):
  1374. """
  1375. Call method.
  1376. Args:
  1377. img (PIL Image): Image to be transformed.
  1378. Returns:
  1379. PIL Image, transformed image.
  1380. """
  1381. return util.uniform_augment(img, self.transforms.copy(), self.num_ops)