Source code for prose.blocks.visualization
import io
import imageio
import matplotlib.pyplot as plt
import numpy as np
from prose.core.block import Block
from prose.utils import z_scale
__all__ = ["VideoPlot", "Video"]
def im_to_255(image):
data = image.copy().astype(float)
data = data / np.max(data)
data = data * 255
return data.astype("uint8")
[docs]class Video(Block):
def __init__(
self,
destination,
fps=10,
compression=None,
data_function=None,
width=None,
contrast=0.1,
name=None,
):
"""
A block to create a video from images data (using ffmpeg).
Parameters
----------
destination : str
The path to save the resulting video.
fps : int, optional
The frames per second of the resulting video. Default is 10.
compression : int, optional
The compression rate of the resulting video (-cr value of fmmpeg).
Default is None.
data_function : callable, optional
A function to apply to each image data before adding it to the video.
If none, a z scale is applied to the data with a contrast given by
:code:`contrast`.Default is None.
width : int, optional
The width in pixels of the resulting video.
Default is None (i.e. original image size).
contrast : float, optional
The contrast of the resulting video. Default is 0.1.
Either :code:`contrast` or :code:`data_function` must be provided.
name : str, optional
The name of the block. Default is None.
Attributes
----------
citations : list of str
The citations for the block.
Methods
-------
run(image)
Adds an image to the video.
terminate()
Closes the video writer.
"""
super().__init__(name=name)
if data_function is None:
def data_function(data):
new_data = data.copy()
new_data = z_scale(new_data, c=contrast)
return new_data
output = []
if compression is not None:
output += ["-crf", f"{compression}"]
if width is not None:
output += ["-vf", f"scale={width}:-1"]
self.writer = imageio.get_writer(
destination,
mode="I",
fps=fps,
output_params=output if len(output) > 0 else None,
)
self.function = data_function
[docs] def run(self, image):
data = self.function(image.data)
self.writer.append_data(im_to_255(data))
[docs] def terminate(self):
self.writer.close()
@property
def citations(self):
return super().citations + ["imageio"]
[docs]class VideoPlot(Video):
def __init__(
self,
plot_function,
destination,
fps=10,
compression=None,
width=None,
name=None,
):
"""
A block to create a video from a matploltib plot (using ffmpeg).
Parameters
----------
plot_function : callable
A function that takes an image as input and produce a plot.
destination : str
The path to save the resulting video.
fps : int, optional
The frames per second of the resulting video. Default is 10.
compression : int, optional
The compression rate of the resulting video (-cr value of fmmpeg).
Default is None.
width : int, optional
The width in pixels of the resulting video.
Default is None (i.e. original image size).
name : str, optional
The name of the block. Default is None.
Attributes
----------
citations : list of str
The citations for the block.
Methods
-------
run(image)
Adds a plot to the video.
terminate()
Closes the video writer.
"""
super().__init__(
destination,
fps=fps,
compression=compression,
width=width,
name=name,
)
self.plot_function = plot_function
[docs] def run(self, image):
self.plot_function(image)
buf = io.BytesIO()
plt.savefig(buf)
self.writer.append_data(imageio.imread(buf))
plt.close()
[docs] def terminate(self):
plt.close()
super().terminate()