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.

tensorflow_image.py 25 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. import tensorflow as tf
  2. import numpy as np
  3. from tensorflow.python.ops import math_ops
  4. from tensorflow.python.ops import array_ops
  5. from tensorflow.python.framework import ops
  6. from tensorflow.python.ops.image_ops_impl import _AssertAtLeast3DImage
  7. from tensorflow.python.framework import dtypes
  8. from tensorflow.python.ops.image_ops_impl import convert_image_dtype
  9. import numbers
  10. __all__ = [
  11. 'CentralCrop',
  12. 'HsvToRgb',
  13. 'AdjustBrightness',
  14. 'AdjustContrast',
  15. 'AdjustHue',
  16. 'AdjustSaturation',
  17. 'Crop',
  18. 'FlipHorizontal',
  19. 'FlipVertical',
  20. 'GrayToRgb',
  21. 'Standardization',
  22. 'RgbToGray',
  23. 'PadToBoundingbox',
  24. 'Pad',
  25. 'RandomBrightness',
  26. 'RandomContrast',
  27. 'RandomHue',
  28. 'RandomSaturation',
  29. 'RandomCrop',
  30. 'Resize',
  31. 'CropAndResize',
  32. 'CropOrPad',
  33. 'ResizeAndPad',
  34. 'RgbToHsv',
  35. 'Transpose',
  36. 'RandomRotation',
  37. 'RandomShift',
  38. 'RandomShear',
  39. 'RandomZoom',
  40. 'Rescale',
  41. 'RandomFlipVertical',
  42. 'RandomFlipHorizontal',
  43. 'HWC2CHW',
  44. 'CHW2HWC',
  45. ]
  46. def CentralCrop(image, central_fraction=None, size=None):
  47. '''
  48. Parameters
  49. ----------
  50. image :
  51. input Either a 3-D float Tensor of shape [height, width, depth],
  52. or a 4-D Tensor of shape [batch_size, height, width, depth].
  53. central_fraction :
  54. float (0, 1], fraction of size to crop
  55. size:
  56. size (Union[int, sequence]) – The output size of the cropped image. If size is an integer, a square crop of size (size, size) is returned.
  57. If size is a sequence of length 2, it should be (height, width).
  58. Returns :
  59. 3-D / 4-D float Tensor, as per the input.
  60. -------
  61. If backend is tensorflow, central_fraction will be used preferentially. if size is used,the height-width ratio will be equivalent to original ratio..
  62. If backend is mindspore, size will be used preferentially.
  63. '''
  64. if size is None and central_fraction is None:
  65. raise ValueError('central_fraction and size can not be both None')
  66. if central_fraction is None:
  67. outshape = np.shape(image)
  68. if len(outshape) == 3:
  69. h_axis = 0
  70. w_axis = 1
  71. elif len(outshape) == 4:
  72. h_axis = 1
  73. w_axis = 2
  74. if isinstance(size, numbers.Number):
  75. target_height = size
  76. target_width = size
  77. elif isinstance(size, tuple) or isinstance(size, list):
  78. if len(size) == 2:
  79. target_height = size[0]
  80. target_width = size[1]
  81. else:
  82. raise ValueError('The length of size must be 2')
  83. else:
  84. raise ValueError("Size should be a single integer or a list/tuple (h, w) of length 2.")
  85. if target_height > outshape[h_axis] or target_width > outshape[w_axis]:
  86. raise ValueError("Centralcrop image size must < original image size.")
  87. central_fraction = max(target_height / outshape[h_axis], target_width / outshape[w_axis])
  88. else:
  89. if central_fraction > 1 or central_fraction <= 0:
  90. raise ValueError('central_fraction must be in (0,1].')
  91. return tf.image.central_crop(image, central_fraction)
  92. def HsvToRgb(image):
  93. return tf.image.hsv_to_rgb(image)
  94. def AdjustBrightness(image, factor):
  95. return tf.image.adjust_brightness(image, delta=factor)
  96. def AdjustContrast(image, factor):
  97. return tf.image.adjust_contrast(image, contrast_factor=factor)
  98. def AdjustHue(image, factor):
  99. return tf.image.adjust_hue(image, delta=factor)
  100. def AdjustSaturation(image, factor):
  101. return tf.image.adjust_saturation(image, saturation_factor=factor)
  102. def Crop(image, offset_height, offset_width, target_height, target_width, is_hwc=True):
  103. '''
  104. Parameters
  105. ----------
  106. image:
  107. A image or a batch of images
  108. offset_height:
  109. Vertical coordinate of the top-left corner of the result in the input.
  110. offset_width:
  111. Horizontal coordinate of the top-left corner of the result in the input.
  112. target_height:
  113. Height of the result.
  114. target_width:
  115. Width of the result.
  116. Returns:
  117. Output [batch, target_height, target_width, channels] or [target_height, target_width, channels]
  118. -------
  119. '''
  120. return tf.image.crop_to_bounding_box(image, offset_height, offset_width, target_height, target_width)
  121. def FlipHorizontal(image):
  122. return tf.image.flip_left_right(image)
  123. def FlipVertical(image):
  124. return tf.image.flip_up_down(image)
  125. def GrayToRgb(image):
  126. return tf.image.grayscale_to_rgb(image)
  127. def RgbToGray(image):
  128. return tf.image.rgb_to_grayscale(image)
  129. def PadToBoundingbox(image, offset_height, offset_width, target_height, target_width, padding_value=0, is_hwc=True):
  130. return tf.image.pad_to_bounding_box(
  131. image,
  132. offset_height,
  133. offset_width,
  134. target_height,
  135. target_width,
  136. )
  137. def Pad(image, padding, padding_value=0, mode='constant'):
  138. '''
  139. Parameters
  140. ----------
  141. image:
  142. A 3-D or 4-D Tensor.
  143. padding:
  144. An integer or a list/tuple. If a single number is provided, pad all borders with this value.
  145. If a tuple or list of 2 values is provided, pad the left and top with the first value and the right and bottom with the second value.
  146. If 4 values are provided as a list or tuple, pad the (top, bottom, left, right) respectively.
  147. padding_value:
  148. In "CONSTANT" mode, the scalar pad value to use. Must be same type as tensor.
  149. mode:
  150. One of "CONSTANT", "REFLECT", or "SYMMETRIC" (case-insensitive)
  151. Returns:
  152. A padded Tensor. Has the same type as tensor.
  153. -------
  154. '''
  155. image_shape = image.shape
  156. if len(image_shape) == 3:
  157. batch_size = 0
  158. elif len(image_shape) == 4:
  159. batch_size = image_shape[0]
  160. else:
  161. raise TypeError('Image must be a 3-D tensor or 4-D tensor.')
  162. if isinstance(padding, int):
  163. padding = ((padding, padding), (padding, padding))
  164. elif isinstance(padding, list) or isinstance(padding, tuple):
  165. if len(padding) == 2:
  166. padding = ((padding[0], padding[0]), (padding[1], padding[1]))
  167. elif len(padding) == 4:
  168. padding = ((padding[0], padding[1]), (padding[2], padding[3]))
  169. else:
  170. raise ValueError('The length of padding should be 2 or 4, but got {}.'.format(len(padding)))
  171. else:
  172. raise TypeError('Padding should be an integer or a list/tuple, but got {}.'.format(type(padding)))
  173. if batch_size == 0:
  174. padding = (padding[0], padding[1], (0, 0))
  175. else:
  176. padding = ((0, 0), padding[0], padding[1], (0, 0))
  177. return tf.pad(image, padding, mode=mode, constant_values=padding_value)
  178. def Standardization(image, mean=None, std=None, channel_mode=False):
  179. '''
  180. Parameters
  181. ----------
  182. image:
  183. An n-D Tensor with at least 3 dimensions, the last 3 of which are the dimensions of each image.
  184. mean:
  185. List or tuple of mean values for each channel, with respect to channel order.
  186. std:
  187. List or tuple of standard deviations for each channel.
  188. channel_mode:
  189. Decide to implement standardization on whole image or each channel of image.
  190. Returns:
  191. A Tensor with the same shape and dtype as image.
  192. -------
  193. '''
  194. image = tf.cast(image, tf.float32)
  195. with ops.name_scope(None, 'Standardization', [image]) as scope:
  196. image = ops.convert_to_tensor(image, name='image')
  197. image = _AssertAtLeast3DImage(image)
  198. orig_dtype = image.dtype
  199. if orig_dtype not in [dtypes.float16, dtypes.float32]:
  200. image = convert_image_dtype(image, dtypes.float32)
  201. if mean is not None and std is not None:
  202. mean = np.array(mean, dtype=np.float32)
  203. std = np.array(std, dtype=np.float32)
  204. image -= mean
  205. image = math_ops.divide(image, std, name=scope)
  206. return convert_image_dtype(image, orig_dtype, saturate=True)
  207. elif mean is None and std is None:
  208. if channel_mode:
  209. num_pixels = math_ops.reduce_prod(array_ops.shape(image)[-3:-1])
  210. #`num_pixels` is the number of elements in each channels of 'image'
  211. image_mean = math_ops.reduce_mean(image, axis=[-2, -3], keepdims=True)
  212. # `image_mean` is the mean of elements in each channels of 'image'
  213. stddev = math_ops.reduce_std(image, axis=[-2, -3], keepdims=True)
  214. min_stddev = math_ops.rsqrt(math_ops.cast(num_pixels, image.dtype))
  215. adjusted_sttdev = math_ops.maximum(stddev, min_stddev)
  216. image -= image_mean
  217. image = math_ops.divide(image, adjusted_sttdev, name=scope)
  218. return convert_image_dtype(image, orig_dtype, saturate=True)
  219. else:
  220. num_pixels = math_ops.reduce_prod(array_ops.shape(image)[-3:])
  221. #`num_pixels` is the number of elements in `image`
  222. image_mean = math_ops.reduce_mean(image, axis=[-1, -2, -3], keepdims=True)
  223. # Apply a minimum normalization that protects us against uniform images.
  224. stddev = math_ops.reduce_std(image, axis=[-1, -2, -3], keepdims=True)
  225. min_stddev = math_ops.rsqrt(math_ops.cast(num_pixels, image.dtype))
  226. adjusted_stddev = math_ops.maximum(stddev, min_stddev)
  227. image -= image_mean
  228. image = math_ops.divide(image, adjusted_stddev, name=scope)
  229. return convert_image_dtype(image, orig_dtype, saturate=True)
  230. else:
  231. raise ValueError('std and mean must both be None or not None')
  232. def RandomBrightness(image, factor):
  233. '''
  234. Parameters
  235. ----------
  236. image:
  237. An image or images to adjust
  238. factor:
  239. Float, must be non-negative. Factor must be (0,1). Random range will be [-factor, factor).
  240. Returns:
  241. The brightness-adjusted image(s).
  242. -------
  243. '''
  244. return tf.image.random_brightness(image, factor)
  245. def RandomContrast(image, lower, upper, seed=None):
  246. '''
  247. Parameters
  248. ----------
  249. image:
  250. An image tensor with 3 or more dimensions.
  251. lower:
  252. float. Lower bound for the random contrast factor.
  253. upper:
  254. float. Upper bound for the random contrast factor.
  255. seed:
  256. A Python integer. Used to create a random seed.
  257. Returns:
  258. The contrast-adjusted image(s).
  259. -------
  260. '''
  261. return tf.image.random_contrast(image, lower, upper, seed)
  262. def RandomHue(image, factor, seed=None):
  263. '''
  264. Parameters
  265. ----------
  266. image:
  267. RGB image or images. The size of the last dimension must be 3.
  268. factor:
  269. float. The maximum value for the random factor.
  270. seed:
  271. An operation-specific seed.
  272. Returns:
  273. Adjusted image(s), same shape and DType as `image`.
  274. -------
  275. '''
  276. return tf.image.random_hue(image, factor, seed)
  277. def RandomSaturation(image, lower, upper, seed=None):
  278. '''
  279. Parameters
  280. ----------
  281. image:
  282. RGB image or images. The size of the last dimension must be 3.
  283. lower:
  284. float. Lower bound for the random saturation factor.
  285. upper:
  286. float. Upper bound for the random saturation factor.
  287. seed:
  288. An operation-specific seed.
  289. Returns:
  290. Adjusted image(s), same shape and DType as `image`.
  291. -------
  292. '''
  293. return tf.image.random_saturation(image, lower, upper, seed)
  294. def RandomCrop(image, size):
  295. '''
  296. Parameters
  297. ----------
  298. image:
  299. Input an image to crop.
  300. size:
  301. a list or tuple. if size is an integer, shape of cropped image will be [size, size, 3]. if length of size is 2.
  302. shape of cropped image will be [height, width, 3].
  303. Returns:
  304. A cropped image of the same rank as image and shape size.
  305. -------
  306. '''
  307. if isinstance(size, int):
  308. crop_size = (size, size)
  309. elif isinstance(size, (list, tuple)) and len(size) == 2:
  310. crop_size = (size[0], size[1])
  311. else:
  312. raise ValueError("Size should be a single integer or a list/tuple (h, w) of length 2.")
  313. if len(image.shape) == 3:
  314. h, w, c = image.shape
  315. crop_size = crop_size + (c, )
  316. elif len(image.shape) == 4:
  317. b, h, w, c = image.shape
  318. crop_size = (b, ) + crop_size + (c, )
  319. return tf.image.random_crop(image, size=crop_size)
  320. def Resize(image, size, method='bilinear', preserve_aspect_ratio=False, antialias=False):
  321. '''
  322. Parameters
  323. ----------
  324. images:
  325. Input an image to resize
  326. size:
  327. if size is an integer, shape of resized image will be [size, size, 3]. if length of size is 2.
  328. shape of resized image will be [height, width, 3].
  329. method:
  330. An image.ResizeMethod, or string equivalent shoulid be in
  331. (bilinear, lanczos3, lanczos5, bicubic, gaussian, nearest, area, mitchellcubic).
  332. Defaults to bilinear.
  333. preserve_aspect_ratio:
  334. Whether to preserve the aspect ratio.
  335. antialias:
  336. Whether to use an anti-aliasing filter when downsampling an image.
  337. Returns:
  338. an resized image
  339. -------
  340. '''
  341. if isinstance(size, int):
  342. size = [size, size]
  343. elif len(size) != 2:
  344. raise ValueError('Size should be a single integer or a list/tuple (h, w) of length 2.')
  345. return tf.image.resize(image, size, method, preserve_aspect_ratio, antialias)
  346. def CropAndResize(image, boxes, box_indices, crop_size, method='bilinear', extrapolation_value=0, is_hwc=True):
  347. '''
  348. Parameters
  349. ----------
  350. image:
  351. A 4-D tensor of shape [batch, image_height, image_width, depth]. Both image_height and image_width need to be positive.
  352. boxes:
  353. A 2-D tensor of shape [num_boxes, 4].
  354. box_indices:
  355. A 1-D tensor of shape [num_boxes] with int32 values in [0,batch).
  356. The value of box_ind[i] specifies the image that the i-th box refers to.
  357. crop_size:
  358. A 1-D tensor of 2 elements, size = [crop_height, crop_width]. All cropped image patches are resized to this size.
  359. The aspect ratio of the image content is not preserved. Both crop_height and crop_width need to be positive.
  360. method:
  361. An optional string specifying the sampling method for resizing.
  362. It can be either "bilinear" or "nearest" and default to "bilinear".
  363. extrapolation_value:
  364. An optional float. Defaults to 0. Value used for extrapolation, when applicable.
  365. Returns:
  366. A 4-D tensor of shape [num_boxes, crop_height, crop_width, depth].
  367. -------
  368. '''
  369. image_shape = image.shape
  370. boxes_num = 0
  371. if isinstance(boxes, tf.Tensor):
  372. boxes_num = boxes.shape[0]
  373. elif isinstance(boxes, np.ndarray) or isinstance(boxes, list) or isinstance(boxes, tuple):
  374. boxes = tf.constant(boxes)
  375. boxes_num = boxes.shape[0]
  376. if isinstance(crop_size, int):
  377. crop_size = (crop_size, crop_size)
  378. crop_size = tf.constant(crop_size)
  379. elif isinstance(crop_size, np.ndarray) or isinstance(crop_size, list) or isinstance(crop_size, tuple):
  380. crop_size = tf.constant(crop_size)
  381. if isinstance(box_indices, np.ndarray) or isinstance(box_indices, list) or isinstance(box_indices, tuple):
  382. box_indices = tf.constant(box_indices)
  383. # if input is an image.
  384. # a 3-D Tensor of shape [image_height, image_width, depth] should use 'tf.expand_dims(image, axis = 0)'
  385. # to convert input to a 4-D Tensor of shape [batch_size,image_height, image_width, depth]
  386. if len(image_shape) == 3:
  387. image = tf.expand_dims(image, axis=0)
  388. box_indices = np.zeros((boxes_num), dtype=np.int)
  389. box_indices = tf.constant(box_indices)
  390. return tf.image.crop_and_resize(
  391. image, boxes=boxes, box_indices=box_indices, crop_size=crop_size, method=method,
  392. extrapolation_value=extrapolation_value
  393. )
  394. def CropOrPad(image, target_height, target_width, is_hwc=True):
  395. '''
  396. Resizes an image to a target width and height by either centrally cropping the image or padding it evenly with zeros.
  397. Parameters
  398. ----------
  399. image:
  400. 4-D Tensor of shape [batch, height, width, channels] or 3-D Tensor of shape [height, width, channels].
  401. target_height:
  402. Target height.
  403. target_width:
  404. Target width.
  405. Returns:
  406. Cropped and/or padded image.
  407. -------
  408. '''
  409. return tf.image.resize_with_crop_or_pad(image, target_height, target_width)
  410. def ResizeAndPad(image, target_height, target_width, method='bilinear', antialias=False, is_hwc=True):
  411. '''
  412. Parameters
  413. ----------
  414. image:
  415. 4-D Tensor of shape [batch, height, width, channels] or 3-D Tensor of shape [height, width, channels].
  416. target_height:
  417. Target height.
  418. target_width:
  419. Target height.
  420. is_hwc:
  421. The flag of image shape, (H, W, C) or (N, H, W, C) if True and (C, H, W) or (N, C, H, W) if False (default=True).
  422. Returns:
  423. Resized and padded image. If images was 4-D, a 4-D float Tensor of shape [batch, new_height, new_width, channels].
  424. If images was 3-D, a 3-D float Tensor of shape [new_height, new_width, channels].
  425. -------
  426. '''
  427. return tf.image.resize_with_pad(image, target_height, target_width, method=method, antialias=antialias)
  428. def RgbToHsv(image):
  429. return tf.image.rgb_to_hsv(image)
  430. def Transpose(image, order):
  431. image = ops.convert_to_tensor(image)
  432. image = _AssertAtLeast3DImage(image)
  433. shape = image.get_shape()
  434. if shape.ndims == 3 or shape.ndims is None:
  435. if len(order) != 3:
  436. raise ValueError('if image is 3-D tensor, order should be a list/tuple with length of 3')
  437. return array_ops.transpose(image, order)
  438. elif shape.ndims == 4:
  439. if len(order) != 4:
  440. raise ValueError('if image is 4-D tensor, order should be a list/tuple with length of 4')
  441. return array_ops.transpose(image, order)
  442. else:
  443. raise ValueError('\'image\' must have either 3 or 4 dimensions.')
  444. def RandomRotation(
  445. image, degrees, fill_mode='nearest', fill_value=0, center=None, expand=False, is_hwc=True, interpolation_order=1
  446. ):
  447. if isinstance(image, tf.Tensor):
  448. image = np.asarray(image)
  449. if not isinstance(image, np.ndarray):
  450. raise TypeError('img should be NumPy image. Got {}'.format(type(image)))
  451. if is_hwc:
  452. h, w, c = 0, 1, 2
  453. else:
  454. h, w, c = 1, 2, 0
  455. if fill_mode not in ('constant', 'nearest', 'reflect', 'wrap'):
  456. raise TypeError('fill_mode must be in (constant, nearest, reflect, wrap)')
  457. image = tf.keras.preprocessing.image.random_rotation(
  458. image, degrees, h, w, c, fill_mode, fill_value, interpolation_order
  459. )
  460. return tf.convert_to_tensor(image)
  461. def RandomShift(image, shift, fill_mode='nearest', fill_value=0, is_hwc=True, interpolation_order=1):
  462. '''
  463. Parameters
  464. ----------
  465. image
  466. Input tensor. Must be 3D.
  467. shift:
  468. int or list/tuple, if shift is int, Width shift range will equal to height shift range.
  469. if shift is list/tuple, shift range will be [width fraction, height fraction]
  470. is_hwc:
  471. The flag of image shape, (H, W, C) or (N, H, W, C) if True and (C, H, W) or (N, C, H, W) if False (default=True).
  472. fill_mode:
  473. Points outside the boundaries of the input are filled according to the given mode (one of {'constant', 'nearest', 'reflect', 'wrap'}).
  474. fill_value:
  475. Value used for points outside the boundaries of the input if mode='constant'.
  476. interpolation_order
  477. int, order of spline interpolation. see ndimage.interpolation.affine_transform
  478. Returns
  479. Shifted Numpy image tensor.
  480. -------
  481. '''
  482. if isinstance(image, tf.Tensor):
  483. image = np.asarray(image)
  484. if not isinstance(image, np.ndarray):
  485. raise TypeError('img should be NumPy image. Got {}'.format(type(image)))
  486. if isinstance(shift, numbers.Number):
  487. width_fraction = shift
  488. height_fraction = shift
  489. elif isinstance(shift, list) or isinstance(shift, tuple):
  490. if len(shift) == 2:
  491. width_fraction = shift[0]
  492. height_fraction = shift[1]
  493. else:
  494. raise ValueError('shift must be number or list/tuple of length 2')
  495. if is_hwc:
  496. h, w, c = 0, 1, 2
  497. else:
  498. h, w, c = 1, 2, 0
  499. if fill_mode not in ('constant', 'nearest', 'reflect', 'wrap'):
  500. raise TypeError('fill_mode must be in (constant, nearest, reflect, wrap)')
  501. image = tf.keras.preprocessing.image.random_shift(
  502. image, wrg=width_fraction, hrg=height_fraction, row_axis=h, col_axis=w, channel_axis=c, fill_mode=fill_mode,
  503. cval=fill_value, interpolation_order=interpolation_order
  504. )
  505. return tf.convert_to_tensor(image)
  506. def RandomShear(image, degree, fill_mode='nearest', fill_value=0, is_hwc=True, interpolation_order=1):
  507. '''
  508. Parameters
  509. ----------
  510. image
  511. Input tensor. Must be 3D.
  512. degree:
  513. Transformation intensity in degrees.
  514. is_hwc:
  515. The flag of image shape, (H, W, C) or (N, H, W, C) if True and (C, H, W) or (N, C, H, W) if False (default=True).
  516. fill_mode:
  517. Points outside the boundaries of the input are filled according to the given mode (one of {'constant', 'nearest', 'reflect', 'wrap'}).
  518. fill_value:
  519. Value used for points outside the boundaries of the input if mode='constant'.
  520. interpolation_order
  521. int, order of spline interpolation. see ndimage.interpolation.affine_transform
  522. Returns
  523. Shifted Numpy image tensor.
  524. -------
  525. '''
  526. if isinstance(image, tf.Tensor):
  527. image = np.asarray(image)
  528. if not isinstance(image, np.ndarray):
  529. raise TypeError('img should be NumPy image. Got {}'.format(type(image)))
  530. if is_hwc:
  531. h, w, c = 0, 1, 2
  532. else:
  533. h, w, c = 1, 2, 0
  534. image = tf.keras.preprocessing.image.random_shear(
  535. image, intensity=degree, row_axis=h, col_axis=w, channel_axis=c, fill_mode=fill_mode, cval=fill_value,
  536. interpolation_order=interpolation_order
  537. )
  538. return tf.convert_to_tensor(image)
  539. def RandomZoom(image, zoom_range, fill_mode='nearest', fill_value=0, is_hwc=True, interpolation_order=1):
  540. '''
  541. Parameters
  542. ----------
  543. image:
  544. Input tensor. Must be 3D.
  545. zoom_range:
  546. Tuple of floats; zoom range for width and height.
  547. is_hwc:
  548. The flag of image shape, (H, W, C) or (N, H, W, C) if True and (C, H, W) or (N, C, H, W) if False (default=True).
  549. fill_mode:
  550. Points outside the boundaries of the input are filled according to the given mode (one of {'constant', 'nearest', 'reflect', 'wrap'}).
  551. fill_value:
  552. Value used for points outside the boundaries of the input if mode='constant'.
  553. interpolation_order:
  554. int, order of spline interpolation. see ndimage.interpolation.affine_transform
  555. Returns
  556. Zoomed Numpy image tensor.
  557. -------
  558. '''
  559. if isinstance(image, tf.Tensor):
  560. image = np.asarray(image)
  561. if not isinstance(image, np.ndarray):
  562. raise TypeError('img should be NumPy image. Got {}'.format(type(image)))
  563. if isinstance(zoom_range, numbers.Number):
  564. zoom_range = (zoom_range, zoom_range)
  565. elif isinstance(zoom_range, list) or isinstance(zoom_range, tuple):
  566. if len(zoom_range) == 2:
  567. zoom_range = (zoom_range[0], zoom_range[1])
  568. else:
  569. raise ValueError('shift must be number or list/tuple of length 2')
  570. if is_hwc:
  571. h, w, c = 0, 1, 2
  572. else:
  573. h, w, c = 1, 2, 0
  574. image = tf.keras.preprocessing.image.random_zoom(
  575. image, zoom_range=zoom_range, row_axis=h, col_axis=w, channel_axis=c, fill_mode=fill_mode, cval=fill_value,
  576. interpolation_order=interpolation_order
  577. )
  578. return tf.convert_to_tensor(image)
  579. def Rescale(image, scale, offset=0):
  580. '''
  581. Parameters
  582. ----------
  583. image:
  584. 3-D image or 4-D images
  585. scale:
  586. Float, the scale to apply to the inputs.
  587. offset:
  588. Float, the offset to apply to the inputs.
  589. Returns:
  590. rescaled images
  591. -------
  592. '''
  593. image = tf.cast(image, dtype=tf.float32)
  594. scale = tf.cast(scale, dtype=tf.float32)
  595. offset = tf.cast(offset, dtype=tf.float32)
  596. return image * scale + offset
  597. def RandomFlipVertical(image):
  598. return tf.image.random_flip_up_down(image)
  599. def RandomFlipHorizontal(image):
  600. return tf.image.random_flip_left_right(image)
  601. def HWC2CHW(image):
  602. if (len(image.shape) == 3):
  603. return Transpose(image, (2, 0, 1))
  604. elif (len(image.shape) == 4):
  605. return Transpose(image, (0, 3, 1, 2))
  606. else:
  607. raise ValueError('\'image\' must have either 3 or 4 dimensions.')
  608. def CHW2HWC(image):
  609. if (len(image.shape) == 3):
  610. return Transpose(image, (1, 2, 0))
  611. elif (len(image.shape) == 4):
  612. return Transpose(image, (0, 2, 3, 1))
  613. else:
  614. raise ValueError('\'image\' must have either 3 or 4 dimensions.')

TensorLayer3.0 是一款兼容多种深度学习框架为计算后端的深度学习库。计划兼容TensorFlow, Pytorch, MindSpore, Paddle.