Source code for plugins.corrections.camera_rot_correction

# Copyright 2014 Diamond Light Source Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
.. module:: camera_rot_correction
   :platform: Unix
   :synopsis: A plugin to apply a rotation to projection images
.. moduleauthor:: Malte Storm<malte.storm@diamond.ac.uk>
"""

from savu.plugins.filters.base_filter import BaseFilter
from savu.plugins.driver.cpu_plugin import CpuPlugin
from savu.plugins.utils import register_plugin
from skimage.transform import rotate
import numpy as np


[docs]@register_plugin class CameraRotCorrection(BaseFilter, CpuPlugin): def __init__(self): super(CameraRotCorrection, self).__init__("CameraRotCorrection")
[docs] def pre_process(self): pass
[docs] def process_frames(self, data): return rotate(data[0].astype(np.float64), self.parameters['angle'], center=self.centre, mode='reflect')[tuple(self.new_slice)]
[docs] def post_process(self): pass
[docs] def setup(self): in_dataset, out_dataset = self.get_datasets() in_pData, out_pData = self.get_plugin_datasets() in_pData[0].plugin_data_setup('PROJECTION', 'single') det_y = in_dataset[0].get_data_dimension_by_axis_label('detector_y') det_x = in_dataset[0].get_data_dimension_by_axis_label('detector_x') self.shape = list(in_dataset[0].get_shape()) self.core_dims = in_pData[0].get_core_dimensions() self.use_auto_centre = self.parameters['use_auto_centre'] self.angle = self.parameters['angle'] self.static_crop = self.parameters['crop_edges'] self.auto_crop = self.parameters['auto_crop'] if self.auto_crop and isinstance(self.angle, list): plugin = self.__class__.__name__ msg = "Parameter tuning on the angles in %s plugin is only " \ "possible with auto_crop set to False." % plugin raise Exception(msg) img_dims = self.get_in_datasets()[0].get_shape() if self.use_auto_centre: self.centre = ( img_dims[det_y] // 2 - 0.5 * np.mod(img_dims[det_y], 2), img_dims[det_x] // 2 - 0.5 * np.mod(img_dims[det_x], 2)) else: self.centre = ( self.parameters['centre_y'], self.parameters['centre_x']) # If the data is cropped then the centre of rotation must be shifted # accordingly, e.g if preview is [:, a:b, c:d] then shift is (a, c) shift = self.exp.meta_data.get( in_dataset[0].get_name() + '_preview_starts') self.centre = ( self.centre[0] - shift[det_y], self.centre[1] - shift[det_x]) self.new_slice = [slice(None)] * 2 img_dims = self.get_in_datasets()[0].get_shape() if self.static_crop > 0 and not self.auto_crop: self.new_slice = [ slice(self.static_crop, img_dims[det_y] - self.static_crop), slice(self.static_crop, img_dims[det_x] - self.static_crop)] for ddim in [det_x, det_y]: self.shape[ddim] = self.shape[ddim] - 2 * self.static_crop elif self.auto_crop: xs = np.array([0, 0, img_dims[det_x], img_dims[det_x]]).astype( np.float32) ys = np.array([0, img_dims[det_x], img_dims[det_x], 0]).astype( np.float32) r = np.sqrt((xs - self.centre[1]) ** 2 + (ys - self.centre[0]) ** 2) theta = np.pi + np.arctan2(xs - self.centre[1], ys - self.centre[0]) theta_p = theta + self.angle / 180. * np.pi x_p = np.sort(self.centre[1] - np.sin(theta_p) * r) y_p = np.sort(self.centre[0] - np.cos(theta_p) * r) x0 = np.ceil(max(x_p[0], x_p[1], 0)).astype(int) x1 = np.floor(min(x_p[2], x_p[3], img_dims[det_x])).astype(int) y0 = np.ceil(max(y_p[0], y_p[1], 0)).astype(int) y1 = np.floor(min(y_p[2], y_p[3], img_dims[det_y])).astype(int) self.new_slice = [slice(y0, y1), slice(x0, x1)] self.shape[det_x] = x1 - x0 self.shape[det_y] = y1 - y0 out_dataset[0].create_dataset(patterns=in_dataset[0], axis_labels=in_dataset[0], shape=tuple(self.shape)) out_pData[0].plugin_data_setup('PROJECTION', 'single')