├── LICENSE ├── README.md ├── cityscapes_colormap.txt ├── fonts ├── LICENSE └── OpenSans-Regular.ttf ├── overlays ├── classification_overlay.py ├── detection_overlay.py ├── overlay_factory.py └── semantic_segmentation_overlay.py ├── screenshots ├── classification.png ├── detection.png └── segmentation.png ├── templates └── gallery.html ├── tfrecord_to_imfolder.py └── tfviewer.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Milan Sulc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | ============================================================================== 24 | Note: The used font (fonts/OpenSans-Regular.ttf) has a different license (Apache 2.0, see fonts/LICENSE) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TFRecord Viewer 2 | 3 | "How about checking your data before going deeper?" 4 | 5 | Use TFRecord Viewer to browse contents of TFRecords with object detection/classification/segmentation annotations. 6 | 7 | The viewer runs a Flask server to provide a web gallery with annotation overlays. 8 | I.e. you can run it on your server machine, but browse on your local machine. 9 | 10 | The web gallery displayed with [Fotorama.io](https://fotorama.io/). 11 | 12 | # Examples 13 | 14 | `python3 tfviewer.py datasets/COCO/tfrecord/coco_train.record-00003-of-00100 --labels-to-highlight='car;truck;bus;motorcycle'` 15 | 16 |  17 | 18 | 19 | `python3 tfviewer.py datasets/imagenet/tfrecord/train-00000-of-01024 --overlay classification` 20 | 21 |  22 | 23 | `python3 tfviewer.py tfrecord_samples/semantic_cityscapes_train-00000-of-00010.tfrecord --overlay=segmentation --segmap-colormap-file=./cityscapes_colormap.txt` 24 |  -------------------------------------------------------------------------------- /cityscapes_colormap.txt: -------------------------------------------------------------------------------- 1 | 128,64,128 2 | 244,35,232 3 | 70,70,70 4 | 102,102,156 5 | 190,153,153 6 | 153,153,153 7 | 250,170,30 8 | 220,220,0 9 | 107,142,35 10 | 152,251,152 11 | 70,130,180 12 | 220,20,60 13 | 255,0,0 14 | 0,0,142 15 | 0,0,70 16 | 0,60,100 17 | 0,80,100 18 | 0,0,230 19 | 119,11,32 -------------------------------------------------------------------------------- /fonts/LICENSE: -------------------------------------------------------------------------------- 1 | The used font (OpenSans-Regular.ttf) from Google fonts https://fonts.google.com/specimen/Open+Sans 2 | is licensed by the Apache License, Version 2.0: 3 | 4 | 5 | Apache License 6 | Version 2.0, January 2004 7 | http://www.apache.org/licenses/ 8 | 9 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 10 | 11 | 1. Definitions. 12 | 13 | "License" shall mean the terms and conditions for use, reproduction, 14 | and distribution as defined by Sections 1 through 9 of this document. 15 | 16 | "Licensor" shall mean the copyright owner or entity authorized by 17 | the copyright owner that is granting the License. 18 | 19 | "Legal Entity" shall mean the union of the acting entity and all 20 | other entities that control, are controlled by, or are under common 21 | control with that entity. For the purposes of this definition, 22 | "control" means (i) the power, direct or indirect, to cause the 23 | direction or management of such entity, whether by contract or 24 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 25 | outstanding shares, or (iii) beneficial ownership of such entity. 26 | 27 | "You" (or "Your") shall mean an individual or Legal Entity 28 | exercising permissions granted by this License. 29 | 30 | "Source" form shall mean the preferred form for making modifications, 31 | including but not limited to software source code, documentation 32 | source, and configuration files. 33 | 34 | "Object" form shall mean any form resulting from mechanical 35 | transformation or translation of a Source form, including but 36 | not limited to compiled object code, generated documentation, 37 | and conversions to other media types. 38 | 39 | "Work" shall mean the work of authorship, whether in Source or 40 | Object form, made available under the License, as indicated by a 41 | copyright notice that is included in or attached to the work 42 | (an example is provided in the Appendix below). 43 | 44 | "Derivative Works" shall mean any work, whether in Source or Object 45 | form, that is based on (or derived from) the Work and for which the 46 | editorial revisions, annotations, elaborations, or other modifications 47 | represent, as a whole, an original work of authorship. For the purposes 48 | of this License, Derivative Works shall not include works that remain 49 | separable from, or merely link (or bind by name) to the interfaces of, 50 | the Work and Derivative Works thereof. 51 | 52 | "Contribution" shall mean any work of authorship, including 53 | the original version of the Work and any modifications or additions 54 | to that Work or Derivative Works thereof, that is intentionally 55 | submitted to Licensor for inclusion in the Work by the copyright owner 56 | or by an individual or Legal Entity authorized to submit on behalf of 57 | the copyright owner. For the purposes of this definition, "submitted" 58 | means any form of electronic, verbal, or written communication sent 59 | to the Licensor or its representatives, including but not limited to 60 | communication on electronic mailing lists, source code control systems, 61 | and issue tracking systems that are managed by, or on behalf of, the 62 | Licensor for the purpose of discussing and improving the Work, but 63 | excluding communication that is conspicuously marked or otherwise 64 | designated in writing by the copyright owner as "Not a Contribution." 65 | 66 | "Contributor" shall mean Licensor and any individual or Legal Entity 67 | on behalf of whom a Contribution has been received by Licensor and 68 | subsequently incorporated within the Work. 69 | 70 | 2. Grant of Copyright License. Subject to the terms and conditions of 71 | this License, each Contributor hereby grants to You a perpetual, 72 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 73 | copyright license to reproduce, prepare Derivative Works of, 74 | publicly display, publicly perform, sublicense, and distribute the 75 | Work and such Derivative Works in Source or Object form. 76 | 77 | 3. Grant of Patent License. Subject to the terms and conditions of 78 | this License, each Contributor hereby grants to You a perpetual, 79 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 80 | (except as stated in this section) patent license to make, have made, 81 | use, offer to sell, sell, import, and otherwise transfer the Work, 82 | where such license applies only to those patent claims licensable 83 | by such Contributor that are necessarily infringed by their 84 | Contribution(s) alone or by combination of their Contribution(s) 85 | with the Work to which such Contribution(s) was submitted. If You 86 | institute patent litigation against any entity (including a 87 | cross-claim or counterclaim in a lawsuit) alleging that the Work 88 | or a Contribution incorporated within the Work constitutes direct 89 | or contributory patent infringement, then any patent licenses 90 | granted to You under this License for that Work shall terminate 91 | as of the date such litigation is filed. 92 | 93 | 4. Redistribution. You may reproduce and distribute copies of the 94 | Work or Derivative Works thereof in any medium, with or without 95 | modifications, and in Source or Object form, provided that You 96 | meet the following conditions: 97 | 98 | (a) You must give any other recipients of the Work or 99 | Derivative Works a copy of this License; and 100 | 101 | (b) You must cause any modified files to carry prominent notices 102 | stating that You changed the files; and 103 | 104 | (c) You must retain, in the Source form of any Derivative Works 105 | that You distribute, all copyright, patent, trademark, and 106 | attribution notices from the Source form of the Work, 107 | excluding those notices that do not pertain to any part of 108 | the Derivative Works; and 109 | 110 | (d) If the Work includes a "NOTICE" text file as part of its 111 | distribution, then any Derivative Works that You distribute must 112 | include a readable copy of the attribution notices contained 113 | within such NOTICE file, excluding those notices that do not 114 | pertain to any part of the Derivative Works, in at least one 115 | of the following places: within a NOTICE text file distributed 116 | as part of the Derivative Works; within the Source form or 117 | documentation, if provided along with the Derivative Works; or, 118 | within a display generated by the Derivative Works, if and 119 | wherever such third-party notices normally appear. The contents 120 | of the NOTICE file are for informational purposes only and 121 | do not modify the License. You may add Your own attribution 122 | notices within Derivative Works that You distribute, alongside 123 | or as an addendum to the NOTICE text from the Work, provided 124 | that such additional attribution notices cannot be construed 125 | as modifying the License. 126 | 127 | You may add Your own copyright statement to Your modifications and 128 | may provide additional or different license terms and conditions 129 | for use, reproduction, or distribution of Your modifications, or 130 | for any such Derivative Works as a whole, provided Your use, 131 | reproduction, and distribution of the Work otherwise complies with 132 | the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, 135 | any Contribution intentionally submitted for inclusion in the Work 136 | by You to the Licensor shall be under the terms and conditions of 137 | this License, without any additional terms or conditions. 138 | Notwithstanding the above, nothing herein shall supersede or modify 139 | the terms of any separate license agreement you may have executed 140 | with Licensor regarding such Contributions. 141 | 142 | 6. Trademarks. This License does not grant permission to use the trade 143 | names, trademarks, service marks, or product names of the Licensor, 144 | except as required for reasonable and customary use in describing the 145 | origin of the Work and reproducing the content of the NOTICE file. 146 | 147 | 7. Disclaimer of Warranty. Unless required by applicable law or 148 | agreed to in writing, Licensor provides the Work (and each 149 | Contributor provides its Contributions) on an "AS IS" BASIS, 150 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 151 | implied, including, without limitation, any warranties or conditions 152 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 153 | PARTICULAR PURPOSE. You are solely responsible for determining the 154 | appropriateness of using or redistributing the Work and assume any 155 | risks associated with Your exercise of permissions under this License. 156 | 157 | 8. Limitation of Liability. In no event and under no legal theory, 158 | whether in tort (including negligence), contract, or otherwise, 159 | unless required by applicable law (such as deliberate and grossly 160 | negligent acts) or agreed to in writing, shall any Contributor be 161 | liable to You for damages, including any direct, indirect, special, 162 | incidental, or consequential damages of any character arising as a 163 | result of this License or out of the use or inability to use the 164 | Work (including but not limited to damages for loss of goodwill, 165 | work stoppage, computer failure or malfunction, or any and all 166 | other commercial damages or losses), even if such Contributor 167 | has been advised of the possibility of such damages. 168 | 169 | 9. Accepting Warranty or Additional Liability. While redistributing 170 | the Work or Derivative Works thereof, You may choose to offer, 171 | and charge a fee for, acceptance of support, warranty, indemnity, 172 | or other liability obligations and/or rights consistent with this 173 | License. However, in accepting such obligations, You may act only 174 | on Your own behalf and on Your sole responsibility, not on behalf 175 | of any other Contributor, and only if You agree to indemnify, 176 | defend, and hold each Contributor harmless for any liability 177 | incurred by, or claims asserted against, such Contributor by reason 178 | of your accepting any such warranty or additional liability. 179 | 180 | END OF TERMS AND CONDITIONS 181 | 182 | APPENDIX: How to apply the Apache License to your work. 183 | 184 | To apply the Apache License to your work, attach the following 185 | boilerplate notice, with the fields enclosed by brackets "[]" 186 | replaced with your own identifying information. (Don't include 187 | the brackets!) The text should be enclosed in the appropriate 188 | comment syntax for the file format. We also recommend that a 189 | file or class name and description of purpose be included on the 190 | same "printed page" as the copyright notice for easier 191 | identification within third-party archives. 192 | 193 | Copyright [yyyy] [name of copyright owner] 194 | 195 | Licensed under the Apache License, Version 2.0 (the "License"); 196 | you may not use this file except in compliance with the License. 197 | You may obtain a copy of the License at 198 | 199 | http://www.apache.org/licenses/LICENSE-2.0 200 | 201 | Unless required by applicable law or agreed to in writing, software 202 | distributed under the License is distributed on an "AS IS" BASIS, 203 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 204 | See the License for the specific language governing permissions and 205 | limitations under the License. 206 | -------------------------------------------------------------------------------- /fonts/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulc/tfrecord-viewer/ef56a01a2a374c3fa5a3c8ed5c3f1b23663d2509/fonts/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /overlays/classification_overlay.py: -------------------------------------------------------------------------------- 1 | import io 2 | from PIL import Image, ImageDraw, ImageFont 3 | 4 | 5 | default_color = 'blue' 6 | highlight_color = 'red' 7 | 8 | 9 | class ClassificationOverlay: 10 | 11 | def __init__(self, args): 12 | self.image_key = args.image_key 13 | self.class_label_key = args.class_label_key 14 | self.font = ImageFont.truetype("./fonts/OpenSans-Regular.ttf", 12) 15 | 16 | 17 | def apply_overlay(self, image_bytes, example): 18 | """Apply annotation overlay over input image. 19 | 20 | Args: 21 | image_bytes: JPEG image 22 | example: TF Example - such as via tf.train.Example().ParseFromString(record) 23 | 24 | Returns: 25 | image_bytes_with_overlay: JPEG image with annotation overlay. 26 | """ 27 | img = Image.open(io.BytesIO(image_bytes)) 28 | draw = ImageDraw.Draw(img) 29 | 30 | class_label = self.get_label(example.features.feature) 31 | 32 | w, h = self.font.getsize(class_label) 33 | draw.rectangle((10, 10, 14 + w, 10 + h), fill="white") 34 | 35 | draw.text((10, 10), class_label, fill='blue', font=self.font) 36 | 37 | with io.BytesIO() as output: 38 | img.save(output, format="JPEG") 39 | image_bytes_with_overlay = output.getvalue() 40 | 41 | return image_bytes_with_overlay 42 | 43 | 44 | def get_label(self, feature): 45 | """ From a TF Record Feature, get the image/class label. 46 | 47 | Args: 48 | feature: TF Record Feature 49 | Returns: 50 | label (str): image/class 51 | """ 52 | label = feature[self.class_label_key].bytes_list.value[0].decode("utf-8"); 53 | return label 54 | -------------------------------------------------------------------------------- /overlays/detection_overlay.py: -------------------------------------------------------------------------------- 1 | import io 2 | from PIL import Image, ImageDraw, ImageFont 3 | 4 | 5 | default_color = 'blue' 6 | highlight_color = 'red' 7 | 8 | 9 | class DetectionOverlay: 10 | 11 | def __init__(self, args): 12 | self.args = args 13 | self.labels_to_highlight = args.labels_to_highlight.split(";") 14 | self.font = ImageFont.truetype("./fonts/OpenSans-Regular.ttf", 12) 15 | 16 | def apply_overlay(self, image_bytes, example): 17 | """Apply annotation overlay over input image. 18 | 19 | Args: 20 | image_bytes: JPEG image 21 | example: TF Example - such as via tf.train.Example().ParseFromString(record) 22 | 23 | Returns: 24 | image_bytes_with_overlay: JPEG image with annotation overlay. 25 | """ 26 | 27 | bboxes = self.get_bbox_tuples(example.features.feature) 28 | image_bytes_with_overlay = self.draw_bboxes(image_bytes, bboxes) 29 | return image_bytes_with_overlay 30 | 31 | 32 | def get_bbox_tuples(self, feature): 33 | """ From a TF Record Feature, get a list of tuples representing bounding boxes 34 | 35 | Args: 36 | feature: TF Record Feature 37 | Returns: 38 | bboxes (list of tuples): [ (label, xmin, xmax, ymin, ymax), (label, xmin, xmax, ymin, ymax) , .. ] 39 | """ 40 | bboxes = [] 41 | if self.args.bbox_name_key in feature: 42 | for ibbox, label in enumerate (feature[self.args.bbox_name_key].bytes_list.value): 43 | bboxes.append( (label.decode("utf-8"), 44 | feature[self.args.bbox_xmin_key].float_list.value[ibbox], 45 | feature[self.args.bbox_xmax_key].float_list.value[ibbox], 46 | feature[self.args.bbox_ymin_key].float_list.value[ibbox], 47 | feature[self.args.bbox_ymax_key].float_list.value[ibbox] 48 | ) ) 49 | else: 50 | print("Bounding box key '%s' not present." % (self.args.bbox_name_key)) 51 | return bboxes 52 | 53 | def bbox_color(self, label): 54 | if label in self.labels_to_highlight: 55 | return highlight_color 56 | else: 57 | return default_color 58 | 59 | def bboxes_to_pixels(self, bbox, im_width, im_height): 60 | """ 61 | Convert bounding box coordinates to pixels. 62 | (It is common that bboxes are parametrized as percentage of image size 63 | instead of pixels.) 64 | 65 | Args: 66 | bboxes (tuple): (label, xmin, xmax, ymin, ymax) 67 | im_width (int): image width in pixels 68 | im_height (int): image height in pixels 69 | 70 | Returns: 71 | bboxes (tuple): (label, xmin, xmax, ymin, ymax) 72 | """ 73 | if self.args.coordinates_in_pixels: 74 | return bbox 75 | else: 76 | label, xmin, xmax, ymin, ymax = bbox 77 | return [label, xmin * im_width, xmax * im_width, ymin * im_height, ymax * im_height] 78 | 79 | def draw_bboxes(self, image_bytes, bboxes): 80 | """Draw bounding boxes onto image. 81 | 82 | Args: 83 | image_bytes: JPEG image. 84 | bboxes (list of tuples): [ (label, xmin, xmax, ymin, ymax), (label, xmin, xmax, ymin, ymax) , .. ] 85 | 86 | Returns: 87 | image_bytes: JPEG image including bounding boxes. 88 | """ 89 | img = Image.open(io.BytesIO(image_bytes)) 90 | 91 | draw = ImageDraw.Draw(img) 92 | 93 | width, height = img.size 94 | 95 | for bbox in bboxes: 96 | label, xmin, xmax, ymin, ymax = self.bboxes_to_pixels(bbox, width, height) 97 | draw.rectangle([xmin, ymin, xmax, ymax], outline=self.bbox_color(label)) 98 | 99 | w, h = self.font.getsize(label) 100 | draw.rectangle((xmin, ymin, xmin + w + 4, ymin + h), fill="white") 101 | 102 | draw.text((xmin+4, ymin), label, fill=self.bbox_color(label), font=self.font) 103 | 104 | with io.BytesIO() as output: 105 | if img.mode in ("RGBA", "P"): 106 | img = img.convert("RGB") 107 | img.save(output, format="JPEG") 108 | output_image = output.getvalue() 109 | return output_image 110 | -------------------------------------------------------------------------------- /overlays/overlay_factory.py: -------------------------------------------------------------------------------- 1 | 2 | from . import semantic_segmentation_overlay 3 | from . import detection_overlay 4 | from . import classification_overlay 5 | 6 | 7 | class EmptyOverlay: 8 | """ Class for empty overlay.""" 9 | def __init__(self, args): 10 | self.args = args 11 | 12 | def apply_overlay(self, image_bytes, example): 13 | return image_bytes 14 | 15 | 16 | overlay_map = { 17 | 'detection': detection_overlay.DetectionOverlay, 18 | 'classification': classification_overlay.ClassificationOverlay, 19 | 'segmentation': semantic_segmentation_overlay.SemanticSegmentationOverlay, 20 | 'none': EmptyOverlay 21 | } 22 | 23 | def get_overlay(name, args): 24 | """ Returns overlay object (by name) initialized by arguments args from tfviewer.py. 25 | 26 | Args: 27 | name (str): Name of the image overlay. 28 | args 29 | """ 30 | return overlay_map[name](args) -------------------------------------------------------------------------------- /overlays/semantic_segmentation_overlay.py: -------------------------------------------------------------------------------- 1 | import io 2 | from PIL import Image, ImageDraw, ImageFont 3 | import tensorflow as tf 4 | import numpy as np 5 | from matplotlib import cm 6 | from matplotlib.colors import ListedColormap 7 | import pdb 8 | 9 | default_color = 'blue' 10 | highlight_color = 'red' 11 | 12 | 13 | class SemanticSegmentationOverlay: 14 | 15 | def __init__(self, args): 16 | self.segmap_key = args.segmap_key 17 | self.segmap_format_key = args.segmap_format_key 18 | self.segmap_colormap_file = args.segmap_colormap_file 19 | self.font = ImageFont.truetype("./fonts/OpenSans-Regular.ttf", 12) 20 | self.segmap_raw_divisor_key = args.segmap_raw_divisor_key 21 | 22 | if self.segmap_colormap_file is None: 23 | self.colormap_function = cm.gist_earth 24 | else: 25 | self.colormap_function = self.load_colormap() 26 | 27 | 28 | 29 | def apply_overlay(self, image_bytes, example): 30 | """Apply segmentation overlay over input image. 31 | 32 | Args: 33 | image_bytes: JPEG image. 34 | feature: TF Record Feature 35 | 36 | Returns: 37 | image_bytes_with_overlay: JPEG image with segmentation overlay. 38 | """ 39 | 40 | img = Image.open(io.BytesIO(image_bytes)) 41 | draw = ImageDraw.Draw(img) 42 | 43 | width, height = img.size 44 | 45 | segmap = self.get_segmap(example, height, width) 46 | segmap = self.apply_colormap(segmap) 47 | segmap_img = Image.fromarray(segmap).convert('RGB') 48 | 49 | 50 | out_img = Image.blend(img, segmap_img, 0.5) 51 | 52 | 53 | with io.BytesIO() as output: 54 | out_img.save(output, format="JPEG") 55 | image_bytes_with_overlay = output.getvalue() 56 | 57 | return image_bytes_with_overlay 58 | 59 | 60 | def load_colormap(self): 61 | colormap = np.zeros((256, 3), dtype=np.uint8) 62 | with open(self.segmap_colormap_file, 'rt') as f: 63 | for i, line in enumerate(f): 64 | colormap[i] = np.fromstring(line, sep=",", dtype=int) 65 | listed_colormap = ListedColormap(colormap/255) 66 | return listed_colormap 67 | 68 | def apply_colormap(self, segmap): 69 | cm_array = self.colormap_function(segmap/255) 70 | return np.uint8(cm_array*255) 71 | 72 | def get_segmap(self, example, im_height, im_width): 73 | """ From a TF Record Feature, get the image/class label. 74 | 75 | Args: 76 | feature: TF Record Feature 77 | Returns: 78 | mask (numpy.ndarray): image segmentation mask (0-255) 79 | """ 80 | segmap_format = example.features.feature[self.segmap_format_key].bytes_list.value[0].decode("utf-8") 81 | example = example.SerializeToString() 82 | string_feature = tf.io.FixedLenFeature((), tf.string) 83 | keys_to_features = {self.segmap_key : string_feature, self.segmap_format_key: string_feature} 84 | 85 | parsed_tensors = tf.io.parse_single_example( 86 | example, features=keys_to_features) 87 | 88 | label_shape = tf.stack([im_height, 89 | im_width, 1 90 | ]) 91 | 92 | if segmap_format == "raw": 93 | flattened_label = tf.io.decode_raw( 94 | parsed_tensors[self.segmap_key], out_type=tf.int32) 95 | mask = tf.reshape(flattened_label, label_shape).numpy()[:,:,0] // self.segmap_raw_divisor_key 96 | elif segmap_format == "png": 97 | label = tf.io.decode_image(parsed_tensors[self.segmap_key], channels=1) 98 | mask = label.numpy()[:,:,0] 99 | else: 100 | raise ValueError("Unknown format: "+segmap_format) 101 | 102 | return mask 103 | -------------------------------------------------------------------------------- /screenshots/classification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulc/tfrecord-viewer/ef56a01a2a374c3fa5a3c8ed5c3f1b23663d2509/screenshots/classification.png -------------------------------------------------------------------------------- /screenshots/detection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulc/tfrecord-viewer/ef56a01a2a374c3fa5a3c8ed5c3f1b23663d2509/screenshots/detection.png -------------------------------------------------------------------------------- /screenshots/segmentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sulc/tfrecord-viewer/ef56a01a2a374c3fa5a3c8ed5c3f1b23663d2509/screenshots/segmentation.png -------------------------------------------------------------------------------- /templates/gallery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |