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

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. 

16 

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, ...]`. 

19 

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""" 

23 

24 

25import numpy as np 

26 

27from tensorboard.plugins.image import metadata 

28from tensorboard.plugins.image import summary_v2 

29from tensorboard.util import encoder 

30 

31 

32# Export V2 versions. 

33image = summary_v2.image 

34 

35 

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. 

45 

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]`. 

64 

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 

70 

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 ) 

105 

106 

107def pb(name, images, max_outputs=3, display_name=None, description=None): 

108 """Create a legacy image summary protobuf. 

109 

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. 

113 

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. 

129 

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 

135 

136 images = np.array(images).astype(np.uint8) 

137 if images.ndim != 4: 

138 raise ValueError("Shape %r must have rank 4" % (images.shape,)) 

139 

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) 

145 

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 ) 

154 

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