Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/tensorboard/plugins/image/summary.py: 23%
35 statements
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
« prev ^ index » next coverage.py v7.4.0, created at 2024-01-03 07:57 +0000
1# Copyright 2017 The TensorFlow Authors. All Rights Reserved.
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"""Image summaries and TensorFlow operations to create them.
17An image summary stores the width, height, and PNG-encoded data for zero
18or more images in a rank-1 string array: `[w, h, png0, png1, ...]`.
20NOTE: This module is in beta, and its API is subject to change, but the
21data that it stores to disk will be supported forever.
22"""
25import numpy as np
27from tensorboard.plugins.image import metadata
28from tensorboard.plugins.image import summary_v2
29from tensorboard.util import encoder
32# Export V2 versions.
33image = summary_v2.image
36def op(
37 name,
38 images,
39 max_outputs=3,
40 display_name=None,
41 description=None,
42 collections=None,
43):
44 """Create a legacy image summary op for use in a TensorFlow graph.
46 Arguments:
47 name: A unique name for the generated summary node.
48 images: A `Tensor` representing pixel data with shape `[k, h, w, c]`,
49 where `k` is the number of images, `h` and `w` are the height and
50 width of the images, and `c` is the number of channels, which
51 should be 1, 3, or 4. Any of the dimensions may be statically
52 unknown (i.e., `None`).
53 max_outputs: Optional `int` or rank-0 integer `Tensor`. At most this
54 many images will be emitted at each step. When more than
55 `max_outputs` many images are provided, the first `max_outputs` many
56 images will be used and the rest silently discarded.
57 display_name: Optional name for this summary in TensorBoard, as a
58 constant `str`. Defaults to `name`.
59 description: Optional long-form description for this summary, as a
60 constant `str`. Markdown is supported. Defaults to empty.
61 collections: Optional list of graph collections keys. The new
62 summary op is added to these collections. Defaults to
63 `[Graph Keys.SUMMARIES]`.
65 Returns:
66 A TensorFlow summary op.
67 """
68 # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
69 import tensorflow.compat.v1 as tf
71 if display_name is None:
72 display_name = name
73 summary_metadata = metadata.create_summary_metadata(
74 display_name=display_name, description=description
75 )
76 with tf.name_scope(name), tf.control_dependencies(
77 [
78 tf.assert_rank(images, 4),
79 tf.assert_type(images, tf.uint8),
80 tf.assert_non_negative(max_outputs),
81 ]
82 ):
83 limited_images = images[:max_outputs]
84 encoded_images = tf.map_fn(
85 tf.image.encode_png,
86 limited_images,
87 dtype=tf.string,
88 name="encode_each_image",
89 )
90 image_shape = tf.shape(input=images)
91 dimensions = tf.stack(
92 [
93 tf.as_string(image_shape[2], name="width"),
94 tf.as_string(image_shape[1], name="height"),
95 ],
96 name="dimensions",
97 )
98 tensor = tf.concat([dimensions, encoded_images], axis=0)
99 return tf.summary.tensor_summary(
100 name="image_summary",
101 tensor=tensor,
102 collections=collections,
103 summary_metadata=summary_metadata,
104 )
107def pb(name, images, max_outputs=3, display_name=None, description=None):
108 """Create a legacy image summary protobuf.
110 This behaves as if you were to create an `op` with the same arguments
111 (wrapped with constant tensors where appropriate) and then execute
112 that summary op in a TensorFlow session.
114 Arguments:
115 name: A unique name for the generated summary, including any desired
116 name scopes.
117 images: An `np.array` representing pixel data with shape
118 `[k, h, w, c]`, where `k` is the number of images, `w` and `h` are
119 the width and height of the images, and `c` is the number of
120 channels, which should be 1, 3, or 4.
121 max_outputs: Optional `int`. At most this many images will be
122 emitted. If more than this many images are provided, the first
123 `max_outputs` many images will be used and the rest silently
124 discarded.
125 display_name: Optional name for this summary in TensorBoard, as a
126 `str`. Defaults to `name`.
127 description: Optional long-form description for this summary, as a
128 `str`. Markdown is supported. Defaults to empty.
130 Returns:
131 A `tf.Summary` protobuf object.
132 """
133 # TODO(nickfelt): remove on-demand imports once dep situation is fixed.
134 import tensorflow.compat.v1 as tf
136 images = np.array(images).astype(np.uint8)
137 if images.ndim != 4:
138 raise ValueError("Shape %r must have rank 4" % (images.shape,))
140 limited_images = images[:max_outputs]
141 encoded_images = [encoder.encode_png(image) for image in limited_images]
142 (width, height) = (images.shape[2], images.shape[1])
143 content = [str(width), str(height)] + encoded_images
144 tensor = tf.make_tensor_proto(content, dtype=tf.string)
146 if display_name is None:
147 display_name = name
148 summary_metadata = metadata.create_summary_metadata(
149 display_name=display_name, description=description
150 )
151 tf_summary_metadata = tf.SummaryMetadata.FromString(
152 summary_metadata.SerializeToString()
153 )
155 summary = tf.Summary()
156 summary.value.add(
157 tag="%s/image_summary" % name,
158 metadata=tf_summary_metadata,
159 tensor=tensor,
160 )
161 return summary