Created
August 31, 2014 15:41
-
-
Save pelson/bf7cd805ea2d3eabc6a4 to your computer and use it in GitHub Desktop.
Image manipulation using mpl for @stefanv.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Example of applying text to an image for Stefan VdW. | |
The image is not transfomed throgh the mpl pipeline, and is instead | |
constrained to pixel space of the figure's resulting image. | |
""" | |
def new_figure(width, height): | |
""" | |
Creates a figure, outside of the PyPlot interface, which can draw mpl | |
components on top of an image. | |
""" | |
from matplotlib.backends.backend_agg import FigureCanvasAgg | |
from matplotlib.figure import Figure | |
fig = Figure(figsize=(width / 100., height / 100.), dpi=100) | |
# Create the canvas for the figure (which gets attached to the | |
# figure inside the constructor. | |
FigureCanvasAgg(fig) | |
return fig | |
def figure_image(figure, image): | |
"""Adds a FirgureImage instance to a figure. | |
A FigureImage is an image which is not transformed in the mpl | |
stack, and so its pixels are 1-to-1 with the final figure. If the | |
final figure is not of the **exact** size of the image, parts of the | |
image will either be cropped, or parts of the figure will be empty. | |
""" | |
from matplotlib.image import FigureImage | |
figimg = FigureImage(figure) | |
figimg.set_array(image) | |
figure.images.append(figimg) | |
return figimg | |
def verify(new_img, old_img): | |
import matplotlib.pyplot as plt | |
plt.switch_backend('tkagg') | |
fig, axes = plt.subplots(3, 3, sharex=True, squeeze=True, sharey=True) | |
axes[0, 0].set_title('Original') | |
axes[0, 1].set_title('New') | |
axes[0, 2].set_title('Diff (0 masked)') | |
axes[0, 0].set_ylabel('Red') | |
axes[1, 0].set_ylabel('Green') | |
axes[2, 0].set_ylabel('Blue') | |
for channel in range(3): | |
axes[channel, 0].imshow(old_img[:, :, channel], interpolation='none') | |
axes[channel, 1].imshow(new_img[:, :, channel], interpolation='none') | |
diff = img[:, :, channel] - new_img[:, :, channel] | |
diff = np.ma.masked_equal(diff, 0) | |
axes[channel, 2].imshow(diff) | |
plt.show() | |
if __name__ == '__main__': | |
from skimage.data import lena | |
img = lena() | |
width, height = img.shape[:2] | |
# Create a new figure. This can either be with PyPlot (with the right | |
# dpi etc.) or just by calling the utility function. | |
fig = new_figure(width, height) | |
# fig = plt.figure(figsize=(width / 100., height / 100.), dpi=100) | |
figure_image(fig, img) | |
# Do whatever we want on the figure (a transform=None) will give us | |
# pixel coordinates from the **bottom left** of the figure. | |
text = fig.text(200, 100, 'Hello Lena', size=20) | |
text.set_transform(None) | |
# We can pump this to a file. | |
fig.savefig('out.png', dpi=100) | |
# Or get hold of it as an array. | |
import numpy as np | |
import numpy.ma | |
new_img = np.array(fig.canvas.buffer_rgba()).reshape([width, height, 4]) | |
verify(new_img, img) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@stefanv - threw this together on the train. I'm not sure what's going on with the red channel - looks like the image itself is being modified which is unexpected.
HTH