Newer
Older
Jan Caron
committed
# -*- coding: utf-8 -*-
"""Display holography images with the gradient direction encoded in color"""
Jan Caron
committed
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
Jan Caron
committed
from numpy import pi
from PIL import Image
CDICT = {'red': [(0.00, 1.0, 0.0),
(0.25, 1.0, 1.0),
(0.50, 1.0, 1.0),
(0.75, 0.0, 0.0),
(1.00, 0.0, 1.0)],
'green': [(0.00, 0.0, 0.0),
(0.25, 0.0, 0.0),
(0.50, 1.0, 1.0),
(0.75, 1.0, 1.0),
(1.00, 0.0, 1.0)],
'blue': [(0.00, 1.0, 1.0),
(0.25, 0.0, 0.0),
(0.50, 0.0, 0.0),
(0.75, 0.0, 0.0),
(1.00, 1.0, 1.0)]}
HOLO_CMAP = mpl.colors.LinearSegmentedColormap('my_colormap', CDICT, 256)
def holo_image(phase_map, density=1):
'''Returns a holography image with color-encoded gradient direction.
Arguments:
phase_map - a PhaseMap object storing the phase informations
density - the gain factor for determining the number of contour lines (default: 1)
'''
assert isinstance(phase_map, PhaseMap), 'phase_map has to be a PhaseMap object!'
# Calculate the holography image intensity:
img_holo = (1 + np.cos(density * phase_map.phase * pi/2)) / 2
# Calculate the phase gradients, expressed by magnitude and angle:
phase_grad_y, phase_grad_x = np.gradient(phase_map.phase, phase_map.res, phase_map.res)
phase_angle = (1 - np.arctan2(phase_grad_y, phase_grad_x)/pi) / 2
phase_magnitude = np.hypot(phase_grad_x, phase_grad_y)
phase_magnitude = np.sin(phase_magnitude/phase_magnitude.max() * pi / 2)
# Color code the angle and create the holography image:
rgba = HOLO_CMAP(phase_angle)
rgb = (255.999 * img_holo.T * phase_magnitude.T * rgba[:, :, :3].T).T.astype(np.uint8)
holo_image = Image.fromarray(rgb)
def make_color_wheel():
'''Display a color wheel for the gradient direction.
Arguments:
None
Returns:
None
'''
x = np.linspace(-256, 256, num=512)
y = np.linspace(-256, 256, num=512)
xx, yy = np.meshgrid(x, y)
r = np.sqrt(xx ** 2 + yy ** 2)
# Create the wheel:
color_wheel_magnitude = (1 - np.cos(r * pi/360)) / 2
color_wheel_magnitude *= 0 * (r > 256) + 1 * (r <= 256)
color_wheel_angle = (1 - np.arctan2(xx, -yy)/pi) / 2
# Color code the angle and create the holography image:
rgba = HOLO_CMAP(color_wheel_angle)
rgb = (255.999 * color_wheel_magnitude.T * rgba[:, :, :3].T).T.astype(np.uint8)
color_wheel = Image.fromarray(rgb)
# Plot the color wheel:
fig = plt.figure(figsize=(4, 4))
axis = fig.add_subplot(1, 1, 1, aspect='equal')
axis.imshow(color_wheel, origin='lower')
axis.xaxis.set_major_locator(NullLocator())
axis.yaxis.set_major_locator(NullLocator())
def display(holo_image, title='Holography Image', axis=None, interpolation='none'):
'''Display the color coded holography image resulting from a given phase map.
Arguments:
holo_image - holography image created with the holo_image function of this module
title - the title of the plot (default: 'Holography Image')
axis - the axis on which to display the plot (default: None, creates new figure)
interpolation - defines the interpolation method (default: 'none')
'''
# If no axis is specified, a new figure is created:
if axis is None:
fig = plt.figure()
axis = fig.add_subplot(1, 1, 1, aspect='equal')
axis.imshow(holo_image, origin='lower', interpolation=interpolation)
# Set the title and the axes labels:
plt.tick_params(axis='both', which='major', labelsize=14)
axis.set_title(title, fontsize=18)
axis.set_xlabel('x-axis [px]', fontsize=15)
axis.set_ylabel('y-axis [px]', fontsize=15)
def display_combined(phase_map, density, title='Combined Plot', interpolation='none',
labels=('x-axis [nm]', 'y-axis [nm]', 'phase [rad]')):# TODO DOCSTRING
'''Display a given phase map and the resulting color coded holography image in one plot.
Arguments:
phase_map - the PhaseMap object from which the holography image is calculated
density - the factor for determining the number of contour lines
title - the title of the combined plot (default: 'Combined Plot')
Returns:
None
'''
# Create combined plot and set title:
fig.suptitle(title, fontsize=20)
# Plot holography image:
holo_axis = fig.add_subplot(1, 2, 1, aspect='equal')
display(holo_image(phase_map, density), axis=holo_axis, interpolation=interpolation)
phase_axis = fig.add_subplot(1, 2, 2, aspect='equal')
fig.subplots_adjust(right=0.85)
phase_map.display(axis=phase_axis, labels=('x-axis [nm]', 'y-axis [nm]', 'phase [mrad]'))