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.

tf.image.cs 25 kB

4 years ago
4 years ago
4 years ago
5 years ago
4 years ago
4 years ago
5 years ago
6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*****************************************************************************
  2. Copyright 2018 The TensorFlow.NET Authors. All Rights Reserved.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ******************************************************************************/
  13. using OneOf.Types;
  14. using System;
  15. using System.Buffers.Text;
  16. using Tensorflow.Contexts;
  17. using static Tensorflow.Binding;
  18. namespace Tensorflow
  19. {
  20. public partial class tensorflow
  21. {
  22. public image_internal image = new image_internal();
  23. public class image_internal
  24. {
  25. public Tensor random_flip_up_down(Tensor image, int seed = 0)
  26. => image_ops_impl.random_flip_up_down(image, seed);
  27. public Tensor random_flip_left_right(Tensor image, int seed = 0)
  28. => image_ops_impl.random_flip_left_right(image, seed);
  29. public Tensor flip_left_right(Tensor image)
  30. => image_ops_impl.flip_left_right(image);
  31. public Tensor flip_up_down(Tensor image)
  32. => image_ops_impl.flip_up_down(image);
  33. public Tensor rot90(Tensor image, int k = 1, string name = null)
  34. => image_ops_impl.rot90(image, k, name);
  35. public Tensor transpose(Tensor image, string name = null)
  36. => image_ops_impl.transpose(image, name);
  37. public Tensor central_crop(Tensor image, float central_fraction)
  38. => image_ops_impl.central_crop(image, central_fraction);
  39. public Tensor pad_to_bounding_box(Tensor image, int offset_height, int offset_width, int target_height, int target_width)
  40. => image_ops_impl.pad_to_bounding_box(image, offset_height, offset_width, target_height, target_width);
  41. public Tensor crop_to_bounding_box(Tensor image, int offset_height, int offset_width, int target_height, int target_width)
  42. => image_ops_impl.crop_to_bounding_box(image, offset_height, offset_width, target_height, target_width);
  43. public Tensor resize_image_with_crop_or_pad(Tensor image, object target_height, object target_width)
  44. => image_ops_impl.resize_image_with_crop_or_pad(image, target_height, target_width);
  45. public Tensor resize_images(Tensor images, Tensor size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false,
  46. string name = null)
  47. => image_ops_impl.resize_images(images, size, method, preserve_aspect_ratio, antialias, name);
  48. public Tensor resize_images_v2(Tensor images, Shape size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false,
  49. string name = null)
  50. => image_ops_impl.resize_images_v2(images, size, method, preserve_aspect_ratio, antialias, name);
  51. public Tensor resize_images_v2(Tensor images, Tensor size, string method = ResizeMethod.BILINEAR, bool preserve_aspect_ratio = false, bool antialias = false,
  52. string name = null)
  53. => image_ops_impl.resize_images_v2(images, size, method, preserve_aspect_ratio, antialias, name);
  54. public Tensor resize_images_with_pad(Tensor image, int target_height, int target_width, string method, bool antialias)
  55. => image_ops_impl.resize_images_with_pad(image, target_height, target_width, method, antialias);
  56. public Tensor per_image_standardization(Tensor image)
  57. => image_ops_impl.per_image_standardization(image);
  58. public Tensor random_brightness(Tensor image, float max_delta, int seed = 0)
  59. => image_ops_impl.random_brightness(image, max_delta, seed);
  60. public Tensor random_contrast(Tensor image, float lower, float upper, int seed = 0)
  61. => image_ops_impl.random_contrast(image, lower, upper, seed);
  62. public Tensor adjust_brightness(Tensor image, Tensor delta)
  63. => image_ops_impl.adjust_brightness(image, delta);
  64. public Tensor adjust_contrast(Tensor images, Tensor contrast_factor)
  65. => image_ops_impl.adjust_contrast(images, contrast_factor);
  66. public Tensor adjust_gamma(Tensor image, int gamma = 1, int gain = 1)
  67. => image_ops_impl.adjust_gamma(image, gamma, gain);
  68. public Tensor rgb_to_grayscale(Tensor images, string name = null)
  69. => image_ops_impl.rgb_to_grayscale(images, name);
  70. public Tensor grayscale_to_rgb(Tensor images, string name = null)
  71. => image_ops_impl.grayscale_to_rgb(images, name);
  72. public Tensor random_hue(Tensor image, float max_delta, int seed = 0)
  73. => image_ops_impl.random_hue(image, max_delta, seed);
  74. public Tensor adjust_hue(Tensor image, Tensor delta, string name = null)
  75. => image_ops_impl.adjust_hue(image, delta, name);
  76. public Tensor random_jpeg_quality(Tensor image, float min_jpeg_quality, float max_jpeg_quality, int seed = 0)
  77. => image_ops_impl.random_jpeg_quality(image, min_jpeg_quality, max_jpeg_quality, seed);
  78. public Tensor adjust_jpeg_quality(Tensor image, Tensor jpeg_quality, string name = null)
  79. => image_ops_impl.adjust_jpeg_quality(image, jpeg_quality, name);
  80. public Tensor random_saturation(Tensor image, float lower, float upper, int seed = 0)
  81. => image_ops_impl.random_saturation(image, lower, upper, seed);
  82. public Tensor adjust_saturation(Tensor image, Tensor saturation_factor, string name = null)
  83. => image_ops_impl.adjust_saturation(image, saturation_factor, name);
  84. public Tensor total_variation(Tensor images, string name = null)
  85. => image_ops_impl.total_variation(images, name);
  86. public (Tensor, Tensor, Tensor) sample_distorted_bounding_box(Tensor image_size, Tensor bounding_boxes,
  87. int seed = 0,
  88. Tensor min_object_covered = null,
  89. float[] aspect_ratio_range = null,
  90. float[] area_range = null,
  91. int max_attempts = 100,
  92. bool use_image_if_no_bounding_boxes = false,
  93. string name = null)
  94. => image_ops_impl.sample_distorted_bounding_box_v2(image_size, bounding_boxes, seed, min_object_covered, aspect_ratio_range,
  95. area_range, max_attempts, use_image_if_no_bounding_boxes, name);
  96. public Tensor non_max_suppression(Tensor boxes, Tensor scores, Tensor max_output_size, float iou_threshold = 0.5f,
  97. float score_threshold = -1f / 0f, /*float soft_nms_sigma = 0.0f,*/ string name = null)
  98. => image_ops_impl.non_max_suppression(boxes, scores, max_output_size, iou_threshold, score_threshold, name);
  99. public Tensor non_max_suppression_with_overlaps(Tensor overlaps, Tensor scores, Tensor max_output_size,
  100. float overlap_threshold = 0.5f, float score_threshold = -1 / 0f, string name = null)
  101. => image_ops_impl.non_max_suppression_with_overlaps(overlaps, scores, max_output_size, overlap_threshold, score_threshold, name);
  102. public Tensor rgb_to_yiq(Tensor images)
  103. => image_ops_impl.rgb_to_yiq(images);
  104. public Tensor yiq_to_rgb(Tensor images)
  105. => image_ops_impl.yiq_to_rgb(images);
  106. public Tensor rgb_to_yuv(Tensor images)
  107. => image_ops_impl.rgb_to_yuv(images);
  108. public Tensor yuv_to_rgb(Tensor images)
  109. => image_ops_impl.yuv_to_rgb(images);
  110. public Tensor psnr(Tensor a, Tensor b, Tensor max_val, string name = null)
  111. => image_ops_impl.psnr(a, b, max_val, name);
  112. public Tensor ssim(Tensor img1, Tensor img2, float max_val = 1f, float filter_size = 11f, float filter_sigma = 1.5f,
  113. float k1 = 0.01f, float k2 = 0.03f)
  114. => image_ops_impl.ssim(img1, img2, max_val, filter_size, filter_sigma, k1, k2);
  115. public Tensor ssim_multiscale(Tensor img1, Tensor img2, float max_val, float[] power_factors = null, float filter_size = 11f,
  116. float filter_sigma = 1.5f, float k1 = 0.01f, float k2 = 0.03f)
  117. => image_ops_impl.ssim_multiscale(img1, img2, max_val, power_factors, filter_size, filter_sigma, k1, k2);
  118. public (Tensor, Tensor) image_gradients(Tensor image)
  119. => image_ops_impl.image_gradients(image);
  120. public Tensor sobel_edges(Tensor image)
  121. => image_ops_impl.sobel_edges(image);
  122. /// <summary>
  123. /// Adjust contrast of RGB or grayscale images.
  124. /// </summary>
  125. /// <param name="images">Images to adjust. At least 3-D.</param>
  126. /// <param name="contrast_factor"></param>
  127. /// <param name="name">A float multiplier for adjusting contrast.</param>
  128. /// <returns>The contrast-adjusted image or images.</returns>
  129. public Tensor adjust_contrast(Tensor images, float contrast_factor, string name = null)
  130. => gen_image_ops.adjust_contrastv2(images, contrast_factor, name);
  131. /// <summary>
  132. /// Adjust hue of RGB images.
  133. /// </summary>
  134. /// <param name="images">RGB image or images. The size of the last dimension must be 3.</param>
  135. /// <param name="delta">float. How much to add to the hue channel.</param>
  136. /// <param name="name">A name for this operation (optional).</param>
  137. /// <returns>Adjusted image(s), same shape and DType as `image`.</returns>
  138. /// <exception cref="ValueError">if `delta` is not in the interval of `[-1, 1]`.</exception>
  139. public Tensor adjust_hue(Tensor images, float delta, string name = null)
  140. {
  141. if (tf.Context.executing_eagerly())
  142. {
  143. if (delta < -1f || delta > 1f)
  144. throw new ValueError("delta must be in the interval [-1, 1]");
  145. }
  146. return gen_image_ops.adjust_hue(images, delta, name: name);
  147. }
  148. /// <summary>
  149. /// Adjust saturation of RGB images.
  150. /// </summary>
  151. /// <param name="image">RGB image or images. The size of the last dimension must be 3.</param>
  152. /// <param name="saturation_factor">float. Factor to multiply the saturation by.</param>
  153. /// <param name="name">A name for this operation (optional).</param>
  154. /// <returns>Adjusted image(s), same shape and DType as `image`.</returns>
  155. public Tensor adjust_saturation(Tensor image, float saturation_factor, string name = null)
  156. => gen_image_ops.adjust_saturation(image, saturation_factor, name);
  157. /// <summary>
  158. /// Greedily selects a subset of bounding boxes in descending order of score.
  159. /// </summary>
  160. /// <param name="boxes">
  161. /// A 4-D float `Tensor` of shape `[batch_size, num_boxes, q, 4]`. If `q`
  162. /// is 1 then same boxes are used for all classes otherwise, if `q` is equal
  163. /// to number of classes, class-specific boxes are used.
  164. /// </param>
  165. /// <param name="scores">
  166. /// A 3-D float `Tensor` of shape `[batch_size, num_boxes, num_classes]`
  167. /// representing a single score corresponding to each box(each row of boxes).
  168. /// </param>
  169. /// <param name="max_output_size_per_class">
  170. /// A scalar integer `Tensor` representing the
  171. /// maximum number of boxes to be selected by non-max suppression per class
  172. /// </param>
  173. /// <param name="max_total_size">
  174. /// A int32 scalar representing maximum number of boxes retained
  175. /// over all classes.Note that setting this value to a large number may
  176. /// result in OOM error depending on the system workload.
  177. /// </param>
  178. /// <param name="iou_threshold">
  179. /// A float representing the threshold for deciding whether boxes
  180. /// overlap too much with respect to IOU.
  181. /// </param>
  182. /// <param name="score_threshold">
  183. /// A float representing the threshold for deciding when to
  184. /// remove boxes based on score.
  185. /// </param>
  186. /// <param name="pad_per_class">
  187. /// If false, the output nmsed boxes, scores and classes are
  188. /// padded/clipped to `max_total_size`. If true, the output nmsed boxes, scores and classes are padded to be of length `max_size_per_class`*`num_classes`,
  189. /// unless it exceeds `max_total_size` in which case it is clipped to `max_total_size`. Defaults to false.
  190. /// </param>
  191. /// <param name="clip_boxes">
  192. /// If true, the coordinates of output nmsed boxes will be clipped
  193. /// to[0, 1]. If false, output the box coordinates as it is. Defaults to true.
  194. /// </param>
  195. /// <returns>
  196. /// 'nmsed_boxes': A [batch_size, max_detections, 4] float32 tensor containing the non-max suppressed boxes.
  197. /// 'nmsed_scores': A [batch_size, max_detections] float32 tensor containing the scores for the boxes.
  198. /// 'nmsed_classes': A [batch_size, max_detections] float32 tensor containing the class for boxes.
  199. /// 'valid_detections': A [batch_size] int32 tensor indicating the number of
  200. /// valid detections per batch item. Only the top valid_detections[i] entries
  201. /// in nms_boxes[i], nms_scores[i] and nms_class[i] are valid. The rest of the
  202. /// entries are zero paddings.
  203. /// </returns>
  204. public (Tensor, Tensor, Tensor, Tensor) combined_non_max_suppression(
  205. Tensor boxes,
  206. Tensor scores,
  207. int max_output_size_per_class,
  208. int max_total_size,
  209. float iou_threshold,
  210. float score_threshold,
  211. bool pad_per_class = false,
  212. bool clip_boxes = true)
  213. {
  214. var iou_threshold_t = ops.convert_to_tensor(iou_threshold, TF_DataType.TF_FLOAT, name: "iou_threshold");
  215. var score_threshold_t = ops.convert_to_tensor(score_threshold, TF_DataType.TF_FLOAT, name: "score_threshold");
  216. var max_total_size_t = ops.convert_to_tensor(max_total_size);
  217. var max_output_size_per_class_t = ops.convert_to_tensor(max_output_size_per_class);
  218. return gen_image_ops.combined_non_max_suppression(boxes, scores, max_output_size_per_class_t, max_total_size_t,
  219. iou_threshold_t, score_threshold_t, pad_per_class, clip_boxes);
  220. }
  221. /// <summary>
  222. /// Extracts crops from the input image tensor and resizes them using bilinear sampling or nearest neighbor sampling (possibly with aspect ratio change) to a common output size specified by crop_size. This is more general than the crop_to_bounding_box op which extracts a fixed size slice from the input image and does not allow resizing or aspect ratio change.
  223. /// Returns a tensor with crops from the input image at positions defined at the bounding box locations in boxes.The cropped boxes are all resized(with bilinear or nearest neighbor interpolation) to a fixed size = [crop_height, crop_width].The result is a 4 - D tensor[num_boxes, crop_height, crop_width, depth].The resizing is corner aligned. In particular, if boxes = [[0, 0, 1, 1]], the method will give identical results to using tf.image.resize_bilinear() or tf.image.resize_nearest_neighbor() (depends on the method argument) with align_corners = True.
  224. /// </summary>
  225. /// <param name="image">A Tensor. Must be one of the following types: uint8, uint16, int8, int16, int32, int64, half, float32, float64. A 4-D tensor of shape [batch, image_height, image_width, depth]. Both image_height and image_width need to be positive.</param>
  226. /// <param name="boxes">A Tensor of type float32. A 2-D tensor of shape [num_boxes, 4]. The i-th row of the tensor specifies the coordinates of a box in the box_ind[i] image and is specified in normalized coordinates [y1, x1, y2, x2]. A normalized coordinate value of y is mapped to the image coordinate at y * (image_height - 1), so as the [0, 1] interval of normalized image height is mapped to [0, image_height - 1] in image height coordinates. We do allow y1 > y2, in which case the sampled crop is an up-down flipped version of the original image. The width dimension is treated similarly. Normalized coordinates outside the [0, 1] range are allowed, in which case we use extrapolation_value to extrapolate the input image values.</param>
  227. /// <param name="box_ind">A Tensor of type int32. A 1-D tensor of shape [num_boxes] with int32 values in [0, batch). The value of box_ind[i] specifies the image that the i-th box refers to.</param>
  228. /// <param name="crop_size">A Tensor of type int32. A 1-D tensor of 2 elements, size = [crop_height, crop_width]. All cropped image patches are resized to this size. The aspect ratio of the image content is not preserved. Both crop_height and crop_width need to be positive.</param>
  229. /// <param name="method">An optional string from: "bilinear", "nearest". Defaults to "bilinear". A string specifying the sampling method for resizing. It can be either "bilinear" or "nearest" and default to "bilinear". Currently two sampling methods are supported: Bilinear and Nearest Neighbor.</param>
  230. /// <param name="extrapolation_value">An optional float. Defaults to 0. Value used for extrapolation, when applicable.</param>
  231. /// <param name="name">A name for the operation (optional).</param>
  232. /// <returns>A 4-D tensor of shape [num_boxes, crop_height, crop_width, depth].</returns>
  233. public Tensor crop_and_resize(Tensor image, Tensor boxes, Tensor box_ind, Tensor crop_size, string method = "bilinear", float extrapolation_value = 0f, string name = null) =>
  234. gen_image_ops.crop_and_resize(image, boxes, box_ind, crop_size, method, extrapolation_value, name);
  235. public Tensor decode_jpeg(Tensor contents,
  236. int channels = 0,
  237. int ratio = 1,
  238. bool fancy_upscaling = true,
  239. bool try_recover_truncated = false,
  240. int acceptable_fraction = 1,
  241. string dct_method = "",
  242. string name = null)
  243. => gen_image_ops.decode_jpeg(contents, channels: channels, ratio: ratio,
  244. fancy_upscaling: fancy_upscaling, try_recover_truncated: try_recover_truncated,
  245. acceptable_fraction: acceptable_fraction, dct_method: dct_method);
  246. public Tensor extract_glimpse(Tensor input, Tensor size, Tensor offsets, bool centered = true, bool normalized = true,
  247. bool uniform_noise = true, string name = null)
  248. => image_ops_impl.extract_glimpse(input, size, offsets, centered, normalized, uniform_noise, name);
  249. public (Tensor, Tensor, Tensor, Tensor) combined_non_max_suppression(Tensor boxes, Tensor scores, Tensor max_output_size_per_class,
  250. Tensor max_total_size, float iou_threshold = 0.5f, float score_threshold = -1f / 0f, bool pad_per_class = false, bool clip_boxes = true,
  251. string name = null)
  252. => image_ops_impl.combined_non_max_suppression(boxes, scores, max_output_size_per_class, max_total_size, iou_threshold, score_threshold,
  253. pad_per_class, clip_boxes, name);
  254. public (Tensor, Tensor) non_max_suppression_padded(Tensor boxes, Tensor scores, Tensor max_output_size,
  255. float iou_threshold = 0.5f,
  256. float score_threshold = -1f / 0f,
  257. bool pad_to_max_output_size = false,
  258. string name = null,
  259. bool sorted_input = false,
  260. bool canonicalized_coordinates = false,
  261. int tile_size = 512)
  262. => image_ops_impl.non_max_suppression_padded(boxes, scores, max_output_size, iou_threshold, score_threshold, pad_to_max_output_size,
  263. name, sorted_input, canonicalized_coordinates, tile_size);
  264. public Tensor resize(Tensor image, Shape size, string method = ResizeMethod.BILINEAR)
  265. => image_ops_impl.resize_images_v2(image, size, method: method);
  266. public Tensor resize(Tensor image, Tensor size, string method = ResizeMethod.BILINEAR)
  267. => image_ops_impl.resize_images_v2(image, size, method: method);
  268. public Tensor resize_bilinear(Tensor images, Tensor size, bool align_corners = false, bool half_pixel_centers = false, string name = null)
  269. => gen_image_ops.resize_bilinear(images, size, align_corners: align_corners, half_pixel_centers: half_pixel_centers, name: name);
  270. public Tensor resize_images(Tensor images, Tensor size, string method = ResizeMethod.BILINEAR,
  271. bool preserve_aspect_ratio = false, string name = null)
  272. => image_ops_impl.resize_images(images, size, method: method,
  273. preserve_aspect_ratio: preserve_aspect_ratio, name: name);
  274. public Tensor convert_image_dtype(Tensor image, TF_DataType dtype, bool saturate = false, string name = null)
  275. => gen_image_ops.convert_image_dtype(image, dtype, saturate: saturate, name: name);
  276. public Tensor decode_image(Tensor contents, int channels = 0, TF_DataType dtype = TF_DataType.TF_UINT8,
  277. string name = null, bool expand_animations = true)
  278. => image_ops_impl.decode_image(contents, channels: channels, dtype: dtype,
  279. name: name, expand_animations: expand_animations);
  280. public Tensor encode_png(Tensor contents, string name = null)
  281. => image_ops_impl.encode_png(contents, name: name);
  282. public Tensor encode_jpeg(Tensor contents, string name = null)
  283. => image_ops_impl.encode_jpeg(contents, name: name);
  284. /// <summary>
  285. /// Convenience function to check if the 'contents' encodes a JPEG image.
  286. /// </summary>
  287. /// <param name="contents"></param>
  288. /// <param name="name"></param>
  289. /// <returns></returns>
  290. public Tensor is_jpeg(Tensor contents, string name = null)
  291. => image_ops_impl.is_jpeg(contents, name: name);
  292. /// <summary>
  293. /// Resize `images` to `size` using nearest neighbor interpolation.
  294. /// </summary>
  295. /// <param name="images"></param>
  296. /// <param name="size"></param>
  297. /// <param name="align_corners"></param>
  298. /// <param name="name"></param>
  299. /// <param name="half_pixel_centers"></param>
  300. /// <returns></returns>
  301. public Tensor resize_nearest_neighbor<Tsize>(Tensor images, Tsize size, bool align_corners = false,
  302. string name = null, bool half_pixel_centers = false)
  303. => image_ops_impl.resize_nearest_neighbor(images, size, align_corners: align_corners,
  304. name: name, half_pixel_centers: half_pixel_centers);
  305. public Tensor draw_bounding_boxes(Tensor images, Tensor boxes, Tensor colors = null, string name = null)
  306. => image_ops_impl.draw_bounding_boxes(images, boxes, colors, name);
  307. }
  308. }
  309. }