def array_to_base64_png(array): """Convert an array into base64-enoded PNG image. Args: array: A 2D np.ndarray or nested list of items. Returns: A base64-encoded string the image. The image is grayscale if the array is 2D. The image is RGB color if the image is 3D with lsat dimension equal to 3. """ # TODO(cais): Deal with 3D case. # TODO(cais): If there are None values in here, replace them with all NaNs. array = np.array(array, dtype=np.float32) assert len(array.shape) == 2 healthy_indices = np.where(np.logical_and(np.logical_not(np.isnan(array)), np.logical_not(np.isinf(array)))) # TODO(cais): Deal with case in which there is no health elements, i.e., all # elements are NaN of Inf. minval = np.min(array[healthy_indices]) maxval = np.max(array[healthy_indices]) # TODO(cais): Deal with the case in which minval == maxval. scaled = np.array((array - minval) / (maxval - minval) * 255, dtype=np.uint8) rgb = np.repeat(np.expand_dims(scaled, -1), 3, axis=-1) image_encoded = base64.b64encode(util.encode_png(rgb)) return image_encoded
def array_to_base64_png(array): """Convert an array into base64-enoded PNG image. Args: array: A 2D np.ndarray or nested list of items. Returns: A base64-encoded string the image. The image is grayscale if the array is 2D. The image is RGB color if the image is 3D with lsat dimension equal to 3. Raises: ValueError: If the input `array` is not rank-2, or if the rank-2 `array` is empty. """ # TODO(cais): Deal with 3D case. # TODO(cais): If there are None values in here, replace them with all NaNs. array = np.array(array, dtype=np.float32) if len(array.shape) != 2: raise ValueError("Expected rank-2 array; received rank-%d array." % len(array.shape)) if not np.size(array): raise ValueError("Cannot encode an empty array (size: %s) as image." % (array.shape, )) is_infinity = np.isinf(array) is_positive = array > 0.0 is_positive_infinity = np.logical_and(is_infinity, is_positive) is_negative_infinity = np.logical_and(is_infinity, np.logical_not(is_positive)) is_nan = np.isnan(array) finite_indices = np.where( np.logical_and(np.logical_not(is_infinity), np.logical_not(is_nan))) if np.size(finite_indices): # Finite subset is not empty. minval = np.min(array[finite_indices]) maxval = np.max(array[finite_indices]) scaled = np.array((array - minval) / (maxval - minval) * 255, dtype=np.uint8) rgb = np.repeat(np.expand_dims(scaled, -1), IMAGE_COLOR_CHANNELS, axis=-1) else: rgb = np.zeros(array.shape + (IMAGE_COLOR_CHANNELS, ), dtype=np.uint8) # Color-code pixels that correspond to infinities and nans. rgb[is_positive_infinity] = POSITIVE_INFINITY_RGB rgb[is_negative_infinity] = NEGATIVE_INFINITY_RGB rgb[is_nan] = NAN_RGB image_encoded = base64.b64encode(util.encode_png(rgb)) return image_encoded
def array_to_base64_png(array): """Convert an array into base64-enoded PNG image. Args: array: A 2D np.ndarray or nested list of items. Returns: A base64-encoded string the image. The image is grayscale if the array is 2D. The image is RGB color if the image is 3D with lsat dimension equal to 3. Raises: ValueError: If the input `array` is not rank-2, or if the rank-2 `array` is empty. """ # TODO(cais): Deal with 3D case. # TODO(cais): If there are None values in here, replace them with all NaNs. array = np.array(array, dtype=np.float32) if len(array.shape) != 2: raise ValueError( "Expected rank-2 array; received rank-%d array." % len(array.shape)) if not np.size(array): raise ValueError( "Cannot encode an empty array (size: %s) as image." % (array.shape,)) is_infinity = np.isinf(array) is_positive = array > 0.0 is_positive_infinity = np.logical_and(is_infinity, is_positive) is_negative_infinity = np.logical_and(is_infinity, np.logical_not(is_positive)) is_nan = np.isnan(array) finite_indices = np.where(np.logical_and(np.logical_not(is_infinity), np.logical_not(is_nan))) if np.size(finite_indices): # Finite subset is not empty. minval = np.min(array[finite_indices]) maxval = np.max(array[finite_indices]) scaled = np.array((array - minval) / (maxval - minval) * 255, dtype=np.uint8) rgb = np.repeat(np.expand_dims(scaled, -1), IMAGE_COLOR_CHANNELS, axis=-1) else: rgb = np.zeros(array.shape + (IMAGE_COLOR_CHANNELS,), dtype=np.uint8) # Color-code pixels that correspond to infinities and nans. rgb[is_positive_infinity] = POSITIVE_INFINITY_RGB rgb[is_negative_infinity] = NEGATIVE_INFINITY_RGB rgb[is_nan] = NAN_RGB image_encoded = base64.b64encode(util.encode_png(rgb)) return image_encoded
def pb(name, images, max_outputs=3, display_name=None, description=None): """Create an image summary protobuf. This behaves as if you were to create an `op` with the same arguments (wrapped with constant tensors where appropriate) and then execute that summary op in a TensorFlow session. Arguments: name: A unique name for the generated summary, including any desired name scopes. images: An `np.array` representing pixel data with shape `[k, h, w, c]`, where `k` is the number of images, `w` and `h` are the width and height of the images, and `c` is the number of channels, which should be 1, 3, or 4. max_outputs: Optional `int`. At most this many images will be emitted. If more than this many images are provided, the first `max_outputs` many images will be used and the rest silently discarded. display_name: Optional name for this summary in TensorBoard, as a `str`. Defaults to `name`. description: Optional long-form description for this summary, as a `str`. Markdown is supported. Defaults to empty. Returns: A `tf.Summary` protobuf object. """ images = np.array(images).astype(np.uint8) if images.ndim != 4: raise ValueError('Shape %r must have rank 4' % (images.shape, )) limited_images = images[:max_outputs] encoded_images = [util.encode_png(image) for image in limited_images] (width, height) = (images.shape[2], images.shape[1]) content = [str(width), str(height)] + encoded_images tensor = tf.make_tensor_proto(content, dtype=tf.string) if display_name is None: display_name = name summary_metadata = metadata.create_summary_metadata( display_name=display_name, description=description) summary = tf.Summary() summary.value.add(tag='%s/image_summary' % name, metadata=summary_metadata, tensor=tensor) return summary
def bench(image, thread_count): """Encode `image` to PNG on `thread_count` threads in parallel. Returns: A `float` representing number of seconds that it takes all threads to finish encoding `image`. """ threads = [threading.Thread(target=lambda: util.encode_png(image)) for _ in xrange(thread_count)] start_time = datetime.datetime.now() for thread in threads: thread.start() for thread in threads: thread.join() end_time = datetime.datetime.now() delta = (end_time - start_time).total_seconds() return delta
def pb(name, images, max_outputs=3, display_name=None, description=None): """Create an image summary protobuf. This behaves as if you were to create an `op` with the same arguments (wrapped with constant tensors where appropriate) and then execute that summary op in a TensorFlow session. Arguments: name: A unique name for the generated summary, including any desired name scopes. images: An `np.array` representing pixel data with shape `[k, w, h, c]`, where `k` is the number of images, `w` and `h` are the width and height of the images, and `c` is the number of channels, which should be 1, 3, or 4. max_outputs: Optional `int`. At most this many images will be emitted. If more than this many images are provided, the first `max_outputs` many images will be used and the rest silently discarded. display_name: Optional name for this summary in TensorBoard, as a `str`. Defaults to `name`. description: Optional long-form description for this summary, as a `str`. Markdown is supported. Defaults to empty. Returns: A `tf.Summary` protobuf object. """ images = np.array(images).astype(np.uint8) if images.ndim != 4: raise ValueError('Shape %r must have rank 4' % (images.shape, )) limited_images = images[:max_outputs] encoded_images = [util.encode_png(image) for image in limited_images] (width, height) = (images.shape[1], images.shape[2]) content = [str(width), str(height)] + encoded_images tensor = tf.make_tensor_proto(content, dtype=tf.string) if display_name is None: display_name = name summary_metadata = metadata.create_summary_metadata( display_name=display_name, description=description) summary = tf.Summary() summary.value.add(tag='%s/image_summary' % name, metadata=summary_metadata, tensor=tensor) return summary
def bench(image, thread_count): """Encode `image` to PNG on `thread_count` threads in parallel. Returns: A `float` representing number of seconds that it takes all threads to finish encoding `image`. """ threads = [ threading.Thread(target=lambda: util.encode_png(image)) for _ in xrange(thread_count) ] start_time = datetime.datetime.now() for thread in threads: thread.start() for thread in threads: thread.join() end_time = datetime.datetime.now() delta = (end_time - start_time).total_seconds() return delta
def _frame_generator(self): while True: last_duration = 0 if self.FPS == 0: continue else: time.sleep(max(0, 1/(self.FPS) - last_duration)) start_time = time.time() array = self._fetch_current_frame() image_bytes = util.encode_png(array) frame_text = b'--frame\r\n' content_type = b'Content-Type: image/png\r\n\r\n' response_content = frame_text + content_type + image_bytes + b'\r\n\r\n' last_duration = time.time() - start_time yield response_content
def write_image(array, filename): with tf.gfile.Open(filename, 'w') as image_file: image_file.write(util.encode_png(array))