PRO warpim, imdata, bpmdata, transform, method, imout, bpmout, status, DanIDL_C_code, IMOUTXSIZE = imoutxsize, IMOUTYSIZE = imoutysize, QUIET = quiet ; Description: This module is a general purpose module for applying a coordinate transformation to an image ; array "imdata", taking bad pixels from a bad pixel mask "bpmdata" into account in the correct ; fashion. The module can handle integer pixel shifts (where image interpolation is unnecessary), ; fractional pixel shifts, linear transformations and polynomial transformations of any degree. ; Image interpolation/resampling is performed where necessary, and the user can choose between ; many different types of interpolation synthesis functions, from the most commonly known ; (nearest neighbour, bilinear, sinc) to the most optimal (B-splines, O-MOMS). ; For an excellent discussion of image interpolation and resampling, see the review by ; P. Thevenaz et al. (Thevenaz P., Blu T. & Unser M., 2000, Handbook Of Medical Imaging, ; Processing And Analysis, Editor: Bankman I.N., Academic Press, San Diego CA, USA, 393-420). The ; papers by Blu et al. 2001 (Blu T., Thevenaz P. & Unser M., 2001, IEEE Transactions On Image ; Processing, 10, 7) and Blu et al. 2003 (Blu T., Thevenaz P. & Unser M., 2003, IEEE Transactions ; On Image Processing, 12, 11) have been essential in writing the relevant modules for the ; synthesis functions of B-splines and O-MOMS. ; The user has the option of specifying the size of the output image via the keywords ; IMOUTXSIZE and IMOUTYSIZE. Note also that bad pixels are grown by half the size of the support of ; the chosen synthesis function. Finally, if the module achieves a successful image transformation ; then the resulting image and corresponding bad pixel mask are returned via the parameters ; "imout" and "bpmout" respectively, and the value of the parameter "status" is set to "1". If the ; module fails to transform the input image, then the parameter "status" is set to "0". ; This module will use C++ code if possible to achieve a much faster execution than the default ; IDL code. The C++ code can be up to an astounding factor of ~50 times faster than the IDL code in ; this case, although the actual speed improvement depends on the transformation applied. ; ; Input Parameters: ; ; imdata - FLOAT/DOUBLE ARRAY - An image array to be transformed using the transformation "transform" and ; employing interpolation if necessary. ; bpmdata - BYTE/INTEGER/LONG ARRAY - A bad pixel mask array of the same size as "imdata" which flags bad pixels ; with a value of "0" and good pixels with a value of "1". If this array ; does not have the same dimensions as "imdata", then all image pixels will ; be considered good, and "bpmdata" will be set to an array of the same ; dimensions as "imdata" with all values equal to "1". ; transform - IDL STRUCTURE - An IDL structure containing tags specifying the transformation to apply to the ; input image data. All of the tags specified below are required to be present in ; "transform" by this module, although they can be set to default values if they ; are not relevant: ; ; (i) trans_type - STRING - This tag specifies the type of transformation to be applied. The acceptable ; values are: ; ; int_pix_shift - The module will shift the image by an integer pixel shift in the ; x and/or y directions. This transformation only requires ; information from the "transform" tags "trans_direction", "dx" and ; "dy". All other "transform" tags may be set to any value. This ; transformation does not require image interpolation, and hence ; the value of the parameter "method" is irrelevant in this case. ; frac_pix_shift - The module will shift the image by a non-integer pixel shift in ; the x and/or y directions. This transformation only requires ; information from the "transform" tags "trans_direction", "dx" and ; "dy". All other "transform" tags may be set to any value. ; linear - The module will apply a linear transformation to the image. Linear ; transformations are made up of any mixture of translations, rotations, ; scale changes, and shears. This transformation requires information from ; the "transform" tags "trans_direction", "dx", "dy", "x_xcoeff", "x_ycoeff", ; "y_xcoeff" and "y_ycoeff". All other "transform" tags may be set to any ; value. ; Mathematically, a linear transformation from a coordinate system with ; coordinates (x,y) to a coordinate system with coordinates (x',y') is given ; by: ; ; x' = (x_xcoeff * x) + (x_ycoeff * y) + dx ; y' = (y_xcoeff * x) + (y_ycoeff * y) + dy ; ; polynomial - NOT IMPLEMENTED YET ; ; (ii) trans_direction - STRING - This tag specifies the direction of the transformation. If it is set to ; "in2out", then the transformation is from the input image coordinate system ; to the output image coordinate system. If it is set to "out2in", then the ; transformation is from the output image coordinate system to the input ; image coordinate system. If this tag is not set to either of the values ; "in2out" or "out2in", then it is reset to the value "in2out" as the default ; value. ; ; (iii) dx - INTEGER/LONG/FLOAT/DOUBLE - This tag specifies the pixel shift in the x direction (pix). ; ; (iv) dy - INTEGER/LONG/FLOAT/DOUBLE - This tag specifies the pixel shift in the y direction (pix). ; ; (v) x_xcoeff - FLOAT/DOUBLE - This tag specifies the linear transformation coefficient for the input x ; coordinate when transforming to the output x coordinate (see under "trans_type" ; and "linear" above). ; ; (vi) x_ycoeff - FLOAT/DOUBLE - This tag specifies the linear transformation coefficient for the input y ; coordinate when transforming to the output x coordinate (see under "trans_type" ; and "linear" above). ; ; (vii) y_xcoeff - FLOAT/DOUBLE - This tag specifies the linear transformation coefficient for the input x ; coordinate when transforming to the output y coordinate (see under "trans_type" ; and "linear" above). ; ; (viii) y_ycoeff - FLOAT/DOUBLE - This tag specifies the linear transformation coefficient for the input y ; coordinate when transforming to the output y coordinate (see under "trans_type" ; and "linear" above). ; ; (ix) poly_deg - INTEGER/LONG - NOT IMPLEMENTED YET ; ; (x) x_polycoeffs - FLOAT/DOUBLE VECTOR - NOT IMPLEMENTED YET ; ; (xi) y_polycoeffs - FLOAT/DOUBLE VECTOR - NOT IMPLEMENTED YET ; ; method - STRING - This parameter specifies the interpolation method to be used whenever image data resampling is ; required. The default resampling method is bilinear interpolation. Note that the support in ; pixels of an interpolation method is the size of the pixel base required to calculate the resampled ; pixel values, and consequently bad pixels in the bad pixel mask will grow by half the size of ; the support in all directions. The interpolation methods available in this module are listed here: ; ; nearest_neighbour - Nearest neighbour interpolation. This method requires a support of 1 pixel. ; bilinear - Bilinear interpolation (identical to linear B-spline interpolation). This method ; requires a support of 2 pixels. ; bspline2 - Quadratic B-spline interpolation. This method requires a support of 3 pixels. ; bspline3 - Cubic B-spline interpolation. This method requires a support of 4 pixels. ; bspline4 - Quartic B-spline interpolation. This method requires a support of 5 pixels. ; bspline5 - Quintic B-spline interpolation. This method requires a support of 6 pixels. ; omoms2 - Quadratic optimal maximum-order minimum-support interpolation. This method requires a ; support of 3 pixels. ; omoms3 - Cubic optimal maximum-order minimum-support interpolation. This method requires a ; support of 4 pixels. ; omoms4 - Quartic optimal maximum-order minimum-support interpolation. This method requires a ; support of 5 pixels. ; omoms5 - Quintic optimal maximum-order minimum-support interpolation. This method requires a ; support of 5 pixels. ; ; NOT IMPLEMENTED YET: ; sinc ; windowed sincs ; lanczos3,4,5 etc. ; keys ; ; DanIDL_C_code - STRING - The full directory path indicating where the DanIDL C++ code is installed. The shared ; library of DanIDL C++ routines should exist as "/dist/libDanIDL.so" within ; the installation. ; ; Output Parameters: ; ; imout - DOUBLE ARRAY - The image array "imdata" after being transformed using the transformation "transform". This ; output image will have the same dimensions as "imdata" unless either or both of the keywords ; IMOUTXSIZE and IMOUTYSIZE are set to appropriate values. ; bpmout - INTEGER ARRAY - The bad pixel mask array "bpmdata" after having been updated appropriately during the image ; transformation. This output bad pixel mask will have the same dimensions as "imdata" unless ; either or both of the keywords IMOUTXSIZE and IMOUTYSIZE are set to appropriate values. ; status - INTEGER - If the module successfully transformed the image as required, then "status" is returned with a value ; of 1, otherwise it is returned with a value of 0. ; ; Keywords: ; ; If the keyword IMOUTXSIZE is set to a positive INTEGER (or LONG) value, then the output image "imout", along with the ; output bad pixel mask "bpmout", will be forced to have the size "imoutxsize" along the x axis. ; ; If the keyword IMOUTYSIZE is set to a positive INTEGER (or LONG) value, then the output image "imout", along with the ; output bad pixel mask "bpmout", will be forced to have the size "imoutysize" along the y axis. ; ; If the keyword QUIET is set (as "/QUIET"), then the program will not print any progress messages on screen. This ; functionality is useful if the module is to be called many times within an image processing routine for instance. ; ; Author: Dan Bramich (dmb@ing.iac.es) ; ; History: ; ; 18/08/2008 - Module created (dmb) ; ; This module does the following, treating bad pixels correctly at all stages: ; ; 1) Checks that the input image array "imdata" is an image of the correct number type, and determines its dimensions. ; If "imdata" is not an image of the correct number type, then the module returns without doing anything. ; ; 2) Checks that "bpmdata" has the same dimensions as "imdata" and is of the correct number type. If this is not the ; case, then the module creates a bad pixel mask that flags every pixel in "imdata" as good, using this new bad pixel ; mask to replace the values stored in "bpmdata". ; ; 3) Checks that the parameter "transform" is an IDL structure and that it contains all the required tag names with values ; of the correct number type. If this is not the case, then the module returns without doing anything. ; ; 4) Checks that the transformation direction is specified via the IDL structure "transform" tag name "trans_direction". ; If it is not specified correctly, then the module assumes that the transformation direction is from the input image ; coordinate system to the output image coordinate system. ; ; 5) Checks that the parameter "method" is a variable of STRING type and that it is set to a value that is supported by ; this module. If this is not the case, then the module switches to the default "bilinear" interpolation method. ; ; 6) Determines the required sizes of the output image array and bad pixel mask. These arrays are set to have the same ; dimensions as "imdata", unless either or both of the keywords IMOUTXSIZE and IMOUTYSIZE are set, in which case they ; will have the dimensions specified by the values of these keywords. ; ; 7) If the IDL structure "transform" tag name "trans_type" is set to "int_pix_shift", then the module carries out steps ; (8)-(9) and then finishes. If the IDL structure "transform" tag name "trans_type" is set to "frac_pix_shift", then ; the module carries out steps (10)-(15) and then finishes. If the IDL structure "transform" tag name "trans_type" is set to ; "linear", then the module carries out steps (16)-(23) and then finishes. Finally, if the IDL structure "transform" tag name ; "trans_type" is set to "polynomial", then the module carries out steps (24)-() and then finishes. ; ; 8) Extracts the integer pixel shifts from the IDL structure "transform", and reverses the shifts if the tag name ; "trans_direction" is set to "out2in". ; ; 9) Shifts the input image by determining the overlap between the input image array and the output image array in the output ; image coordinate system, and then filling the overlap region in the output image array with the relevant pixel values ; from the input image array. The input image bad pixel mask is also shifted using the same method. Note that no image ; interpolation is performed in this case. ; ; 10) Extracts the fractional pixel shifts from the IDL structure "transform", and reverses the shifts if the tag name ; "trans_direction" is set to "out2in". ; ; 11) Shifts the input image and bad pixel mask by the integer parts of the pixel shift using the same method as that described ; in step (9). ; ; 12) If either of the fractional parts of the pixel shift are non-zero, then the input image is further shifted using ; interpolation in steps (13)-(15). Otherwise, the module finishes. ; ; 13) If the interpolation method specified by the parameter "method" requires pre-filtering of the image data, then the module ; temporarily interpolates over the bad pixels in the input image array, and then pre-filters the input image using the ; filter appropriate to the chosen interpolation method. ; ; 14) Calculates the relevant convolution kernel for the interpolation method specified by the parameter "method" in order to ; perform the fractional pixel shifts. Note that because of the nature of the transformation, each pixel in the output ; image array can be determined using the same convolution kernel. ; ; 15) Convolves the input image with the convolution kernel, growing bad pixels appropriately. ; ; 16) Extracts the linear transformation coefficients from the IDL structure "transform". If the linear transformation is ; singular (i.e: the determinant is zero), then the module finishes without doing anything. ; ; 17) If the transformation direction, as specified by the tag name "trans_direction" in the IDL structure "transform", is from ; the input image coordinate system to the output image coordinate system, then the module reverses the transformation. ; ; 18) If the interpolation method specified by the parameter "method" requires pre-filtering of the image data, then the module ; temporarily interpolates over the bad pixels in the input image array, and then pre-filters the input image using the ; filter appropriate to the chosen interpolation method. ; ; 19) Determines the level of oversampling necessary in the output image array. ; ; 20) Sets up coordinate arrays representing the coordinates in the oversampled output image, and transforms these coordinates ; to the coordinate system of the input image. ; ; 21) Sets up an oversampled output image array, along with a corresponding bad pixel mask. ; ; 22) Calculates the interpolated pixel values in the oversampled output image array by applying the synthesis function corresponding ; to the interpolation method specified by the parameter "method" to the coordinate arrays created in step (20). ; ; 23) Rebins the oversampled output image array and bad pixel mask to the required size, and enforces flux conservation by scaling ; the output image array by the determinant of the linear transformation (for the transformation direction "out2in"). ; ; 24) NOT IMPLEMENTED YET ;If the keyword QUIET is set, then do not print progress messages ;Check that "imdata" is an image ;If "bpmdata" does not have the same dimensions as "imdata", then assume that all image pixels ;are good ;Check that the IDL structure "transform" contains the required tag names, and return without ;doing anything if this parameter is not specified properly ;Check the values of the required tag names in the IDL structure "transform" ;Check that the transformation direction is specified, otherwise assume that the direction is from ;the input image coordinate system to the output image coordinate system ;Check that "method" is a string ;Check that the interpolation method is supported, and if not, then switch to the default "bilinear" ;interpolation method ;Set up the output image data array and bad pixel mask dimensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Integer pixel shift transformations ;If the type of transformation to be applied to the input image is an integer pixel shift in the ;x and/or y directions ;Extract the integer pixel shifts ;If the transformation direction is specified as transforming from the output image coordinate system ;to the input image coordinate system, then reverse the transformation ;Report the transformation to be applied, along with the interpolation method to be used ;Shift the input image by the integer pixel shifts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Fractional pixel shift transformations ;If the type of transformation to be applied to the input image is a fractional pixel shift in the ;x and/or y directions ;Extract the fractional pixel shifts ;If the transformation direction is specified as transforming from the output image coordinate system ;to the input image coordinate system, then reverse the transformation ;Report the transformation to be applied ;Determine the size of the fractional part of the pixel shift ;Determine the overlap region between the output image array and the input image array after shifting by ;the integer part of the pixel shifts ;If the fractional parts of the pixel shift in both the x and y directions are zero, then the transformation ;is equivalent to an integer pixel shift, which does not require interpolation ;Shift the input image by the integer pixel shifts ;If either of the fractional parts of the pixel shift in the x and y directions are non-zero, then the ;transformation requires interpolation ;If the interpolation method requires pre-filtering of the image data, then do the pre-filtering ;Calculate the relevant convolution kernel ;Convolve the input image with the convolution kernel, growing bad pixels as necessary. This ;operation shifts the input image by the fractional part of the pixel shifts. ;Shift the input image by the integer part of the pixel shifts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Linear transformations ;If the type of transformation to be applied to the input image is a linear transformation ;Extract the linear transformation ;If the linear transformation is singular, then do not apply the transformation ;If the transformation direction is specified as transforming from the input image coordinate system ;to the output image coordinate system, then reverse the transformation ;Report the transformation to be applied ;If the interpolation method requires pre-filtering of the image data, then do the pre-filtering ;Determine the level of oversampling necessary in the output image array ;Set up coordinate arrays representing the coordinates in the oversampled output image, and transform these ;coordinates to the coordinate system of the input image ;Determine if the shared library of DanIDL C++ routines is installed ;Set up an oversampled output image array and various other quantities ;If the shared library of DanIDL C++ routines is installed, then use the C++ code to speed up ;the calculation of the interpolated image values ;Calculate the pixel values in the oversampled output image array ;If the shared library of DanIDL C++ routines is not installed, then use the default IDL code ;For each column in the oversampled output image array ;Report progress ;For each row in the oversampled output image array ;Extract the coordinates in the input image coordinate system of the current output image pixel ;If the current coordinates lie within the boundary of the input image ;Calculate the relevant synthesis function values ;If the current output image pixel does not have a bad pixel from the input image within the ;support of the synthesis function ;Calculate the interpolated pixel value of the current output image pixel ;Rebin the oversampled output image array and bad pixel mask ;Enforce flux conservation by multiplying the output image array by the determinant of the linear transformation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Polynomial transformations ;If the type of transformation to be applied to the input image is a polynomial transformation ;NOT IMPLEMENTED YET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Finish ;Finish