/* $Id: align.c,v 1.3 2002/01/11 08:44:55 fors Exp $ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * COPYRIGHT (c) 2001 European Southern Observatory * LICENSE: GNU General Public License version 2 or later * * PROJECT: VLT Data Flow System * AUTHOR: Ralf Palsa -- ESO/DMD/DPG * SUBSYSTEM: Instrument pipelines * * PURPOSE: * DESCRIPTION: * * $Name: fsmosaic-1_0 $ * $Revision: 1.3 $ * ---------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "align.h" #include "resampling.h" /** * @memo * Compute the horizontal image size from an image transformation. * * @return The function returns the new horizontal size in pixels after * rotation and shifting the image. * * @param image Image object. * @param parameters Transformation parameters. * @param xorigin Location of the new origin along the x axis. * @param fast Fast mode flag. * * @doc * The function computes the horizontal size of an image in pixels, obtained * by transforming the input image \textbf{image} using the transformation * parameters \textbf{param}. * * The transformation parameters are defined as: * \begin{verbatim} * u = t[0].x + t[1].y + t[2] * v = t[3].x + t[4].y + t[5] * \end{verbatim} * * On successful return, \textbf{xorigin} is set to the minimum x location, * i.e. the location of origin along the x axis of transformed image * relative to the original image. * * If the flag \textbf{fast} is non-zero, the horizontal size and the * minimum x localtion is determine from the 4 corners only. Otherwise * each image pixel is used for the size determination. * * @author R. Palsa */ size_t image_compute_hsize(image_t *image, double *parameters, double *xorigin, unsigned int fast) { register int i, j; size_t hsize = 0; double xmin = 0; double xmax = image->hsize - 1; if (!fast) { double x; for (i = 0; i < image->vsize; i++) { for (j = 0; j < image->hsize; j++) { x = parameters[0] * j + parameters[1] * i + parameters[2]; if (x < xmin) xmin = x; else if (x > xmax) xmax = x; } } } else { int jmax = image->hsize - 1; int imax = image->vsize - 1; double corner[4]; /* * Just check the four corners (i = 0, j = 0), (i = 0, j = jmax), * (i = imax, j = 0), (i = imax, j = jmax). * * Whenever i or j is 0 the respective term does not appear below. */ corner[0] = parameters[2]; corner[1] = parameters[0] * jmax + parameters[2]; corner[2] = parameters[1] * imax + parameters[2]; corner[3] = parameters[0] * jmax + parameters[1] * imax + parameters[2]; for (i = 0; i < 4; i++) if (corner[i] < xmin) xmin = corner[i]; else if (corner[i] > xmax) xmax = corner[i]; } xmin = floor(xmin); xmax = ceil(xmax); hsize = (size_t)fabs(xmax - xmin) + 1; if (hsize > IMAGE_HSIZE_MAX) return -1; *xorigin = xmin; return hsize; } /** * @memo * Compute the vertical image size from an image transformation. * * @return The function returns the new vertical size in pixels after * rotation and shifting the image. * * @param image Image object. * @param parameters Transformation parameters. * @param yorigin Location of the new origin along the y axis. * @param fast Fast mode flag. * * @doc * The function computes the vertical size of an image in pixels, obtained * by transforming the input image \textbf{image} using the transformation * parameters \textbf{param}. * * The transformation parameters are defined as: * \begin{verbatim} * u = t[0].x + t[1].y + t[2] * v = t[3].x + t[4].y + t[5] * \end{verbatim} * * On successful return, \textbf{yorigin} is set to the minimum y location, * i.e. the location of origin along the y axis of transformed image * relative to the original image. * * If the flag \textbf{fast} is non-zero, the vertical size and the * minimum y location is determine from the 4 corners only. Otherwise * each image pixel is used for the size determination. * * @author R. Palsa */ size_t image_compute_vsize(image_t *image, double *parameters, double *yorigin, unsigned int fast) { register int i, j; size_t vsize = 0; double ymin = 0; double ymax = image->vsize - 1; if (!fast) { double y; for (i = 0; i < image->vsize; i++) { for (j = 0; j < image->hsize; j++) { y = parameters[3] * j + parameters[4] * i + parameters[5]; if (y < ymin) ymin = y; else if (y > ymax) ymax = y; } } } else { int jmax = image->hsize - 1; int imax = image->vsize - 1; double corner[4]; /* * Just check the four corners (i = 0, j = 0), (i = 0, j = jmax), * (i = imax, j = 0), (i = imax, j = jmax). * * Whenever i or j is 0 the respective term does not appear below. */ corner[0] = parameters[5]; corner[1] = parameters[3] * jmax + parameters[5]; corner[2] = parameters[4] * imax + parameters[5]; corner[3] = parameters[3] * jmax + parameters[4] * imax + parameters[5]; for (i = 0; i < 4; i++) if (corner[i] < ymin) ymin = corner[i]; else if (corner[i] > ymax) ymax = corner[i]; } ymin = floor(ymin); ymax = ceil(ymax); vsize = (size_t)fabs(ymax - ymin) + 1; if (vsize > IMAGE_VSIZE_MAX) return -1; *yorigin = ymin; return vsize; } /** * @memo * Align two images. * * @return The function returns a pointer to the created image object * containing the aligned images. In case an error occurred a #NULL# * pointer is returned. * * @param image1 First image object. * @param image2 Second image object. * @param angle Rotation angle. * @param xshift Shift in pixels along the x axis. * @param yshift Shift in pixels along the y axis. * * @doc * The function rotates the image \textbf{image2} around its center and * and shifts it with respect to \textbf{image1} by the amount of * \textbf{xshift} and \textbf{yshift} pixels along the x and y axis * respectively. Both images are the inserted into the created result * image which is the union of \textbf{image1} and the transformed image * \textbf{image2}. * * @author R. Palsa */ image_t *align_images(image_t *image1, image_t *image2, double angle, double xshift, double yshift, double *xoffset, double *yoffset) { double xmin, ymin; double hsize, vsize; double transformation[6]; image_t *t_image; assert(image1 != 0); assert(image2 != 0); /* * Compute the coefficients of the image transformation. */ angle *= PI_NUMB / 180.; transformation[0] = cos(angle); transformation[1] = -sin(angle); transformation[2] = 0.5 * (image2->hsize * (1. - cos(angle)) + image2->vsize * sin(angle)) + xshift; transformation[3] = sin(angle); transformation[4] = cos(angle); transformation[5] = 0.5 * (image2->vsize * (1. - cos(angle)) - image2->hsize * sin(angle)) + yshift; /* * Compute the size of the transformed image. */ hsize = image_compute_hsize(image2, transformation, &xmin, 1); vsize = image_compute_vsize(image2, transformation, &ymin, 1); /* * Compensate for new image size */ transformation[2] -= xmin; transformation[5] -= ymin; /* * Create the transformed image2. */ if (!(t_image = image_new(hsize, vsize))) return 0; if (!image_transform(t_image, image2, transformation, "sinc2")) { image_del(t_image); return 0; } /* * Insert image1 into the target image. */ if (image_insert(t_image, image1, -xmin, -ymin) == EXIT_FAILURE) { image_del(t_image); return 0; } *xoffset = -xmin; *yoffset = -ymin; return t_image; }