RotateImage2d
Applies a rotation of a given angle and center on a two-dimensional image.
Access to parameter description
This algorithm performs a rotation of an image by a user-defined angle $\theta$ and a center $C$. The new coordinates $(x', y')$ can be expressed as a function of the old coordinates $(x, y)$: $$ \left\{\begin{matrix}x'&=&(x-x_0)\cdot\cos\theta - (y-y_0)\cdot\sin\theta + x_0\\ y'&=&(x-x_0)\cdot\sin\theta + (y-y_0)\cdot\cos\theta + y_0\end{matrix}\right\} $$ where $(x_0,y_0)$ are the coordinates of the center of the rotation. Or in matrix notation: $$ \begin{bmatrix}x'\\y'\end{bmatrix} = \begin{bmatrix}\cos\theta&-\sin\theta\\\sin\theta&\cos\theta\end{bmatrix} \cdot\begin{bmatrix}x-x_0\\y-y_0\end{bmatrix} + \begin{bmatrix}x_0\\y_0\end{bmatrix} $$ Destination pixels may be outside the image, and normally these pixels are ignored. Furthermore, the $(x, y)$ coordinates obtained are not always integers, even though an image is a discrete space. The following figure illustrates the grid of the resultant image, the point $M'$ being a pixel in this image. The points are generated from the rotation of the original image and do not fit on the grid.
Figure 1. Image grid rotation
To calculate the intensity of each pixel $M'$, two methods are possible:
If $d_j$ denotes the distance $M'_j M'$, $f_i$ is defined as: $$ f_i=\prod_{\substack{j=1\\j\neq i}}^{j=4}d_j $$ e.g. $f_1=d_2d_3d_4$.
The choice of the $f_i$'s ensures that the interpolated value is equal to $g'_j$ if $M'$ matches $M'_j$. This method gives better results but requires more computation time.
Notice: RotateImage2d considers the image as a cylinder, where the information outside the image area wraps around and is placed in the blank part.
See also
Access to parameter description
This algorithm performs a rotation of an image by a user-defined angle $\theta$ and a center $C$. The new coordinates $(x', y')$ can be expressed as a function of the old coordinates $(x, y)$: $$ \left\{\begin{matrix}x'&=&(x-x_0)\cdot\cos\theta - (y-y_0)\cdot\sin\theta + x_0\\ y'&=&(x-x_0)\cdot\sin\theta + (y-y_0)\cdot\cos\theta + y_0\end{matrix}\right\} $$ where $(x_0,y_0)$ are the coordinates of the center of the rotation. Or in matrix notation: $$ \begin{bmatrix}x'\\y'\end{bmatrix} = \begin{bmatrix}\cos\theta&-\sin\theta\\\sin\theta&\cos\theta\end{bmatrix} \cdot\begin{bmatrix}x-x_0\\y-y_0\end{bmatrix} + \begin{bmatrix}x_0\\y_0\end{bmatrix} $$ Destination pixels may be outside the image, and normally these pixels are ignored. Furthermore, the $(x, y)$ coordinates obtained are not always integers, even though an image is a discrete space. The following figure illustrates the grid of the resultant image, the point $M'$ being a pixel in this image. The points are generated from the rotation of the original image and do not fit on the grid.
Figure 1. Image grid rotation
To calculate the intensity of each pixel $M'$, two methods are possible:
- Take the gray level of the nearest neighbor. For the above example $M'$ would be given the intensity of $M'_i:g'=g'_i$
- Take into account the four nearest neighbors and calculate the gray level based on the average of the four points, weighted by their distance, as in: $$ g'=\frac{f_1\times g'_1+f_2\times g'_2+f_3\times g'_3+f_4\times g'_4}{f_1+f_2+f_3+f_4} $$
If $d_j$ denotes the distance $M'_j M'$, $f_i$ is defined as: $$ f_i=\prod_{\substack{j=1\\j\neq i}}^{j=4}d_j $$ e.g. $f_1=d_2d_3d_4$.
The choice of the $f_i$'s ensures that the interpolated value is equal to $g'_j$ if $M'$ matches $M'_j$. This method gives better results but requires more computation time.
Notice: RotateImage2d considers the image as a cylinder, where the information outside the image area wraps around and is placed in the blank part.
See also
Function Syntax
This function returns the outputImage output parameter.
// Function prototype. std::shared_ptr< iolink::ImageView > rotateImage2d( std::shared_ptr< iolink::ImageView > inputImage, iolink::Vector2i32 rotationCenter, double rotationAngle, RotateImage2d::InterpolationType interpolationType, std::shared_ptr< iolink::ImageView > outputImage = NULL );
This function returns the outputImage output parameter.
// Function prototype. rotate_image_2d( input_image, rotation_center = [1, 1], rotation_angle = 10, interpolation_type = RotateImage2d.InterpolationType.NEAREST_NEIGHBOR, output_image = None )
This function returns the outputImage output parameter.
// Function prototype. public static IOLink.ImageView RotateImage2d( IOLink.ImageView inputImage, int[] rotationCenter = null, double rotationAngle = 10, RotateImage2d.InterpolationType interpolationType = ImageDev.RotateImage2d.InterpolationType.NEAREST_NEIGHBOR, IOLink.ImageView outputImage = null );
Class Syntax
Parameters
Class Name | RotateImage2d |
---|
Parameter Name | Description | Type | Supported Values | Default Value | |||||
---|---|---|---|---|---|---|---|---|---|
inputImage |
The input image. | Image | Binary, Label, Grayscale or Multispectral | nullptr | |||||
rotationCenter |
The rotation center coordinates. | Vector2i32 | >=0 | {1, 1} | |||||
rotationAngle |
The angle of the rotation in degrees. | Float64 | Any value | 10 | |||||
interpolationType |
The interpolation mode. Method used to calculate the intensity of each pixel in the result image.
|
Enumeration | NEAREST_NEIGHBOR | ||||||
outputImage |
The output image. Its dimensions and type are forced to the same values as the input. | Image | nullptr |
Object Examples
std::shared_ptr< iolink::ImageView > polystyrene = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "polystyrene.tif" ); RotateImage2d rotateImage2dAlgo; rotateImage2dAlgo.setInputImage( polystyrene ); rotateImage2dAlgo.setRotationCenter( {1, 1} ); rotateImage2dAlgo.setRotationAngle( 10.0 ); rotateImage2dAlgo.setInterpolationType( RotateImage2d::InterpolationType::NEAREST_NEIGHBOR ); rotateImage2dAlgo.execute(); std::cout << "outputImage:" << rotateImage2dAlgo.outputImage()->toString();
polystyrene = ioformat.read_image(imagedev_data.get_image_path("polystyrene.tif")) rotate_image_2d_algo = imagedev.RotateImage2d() rotate_image_2d_algo.input_image = polystyrene rotate_image_2d_algo.rotation_center = [1, 1] rotate_image_2d_algo.rotation_angle = 10.0 rotate_image_2d_algo.interpolation_type = imagedev.RotateImage2d.NEAREST_NEIGHBOR rotate_image_2d_algo.execute() print( "output_image:", str( rotate_image_2d_algo.output_image ) )
ImageView polystyrene = ViewIO.ReadImage( @"Data/images/polystyrene.tif" ); RotateImage2d rotateImage2dAlgo = new RotateImage2d { inputImage = polystyrene, rotationCenter = new int[]{1, 1}, rotationAngle = 10.0, interpolationType = RotateImage2d.InterpolationType.NEAREST_NEIGHBOR }; rotateImage2dAlgo.Execute(); Console.WriteLine( "outputImage:" + rotateImage2dAlgo.outputImage.ToString() );
Function Examples
std::shared_ptr< iolink::ImageView > polystyrene = ioformat::readImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "polystyrene.tif" ); auto result = rotateImage2d( polystyrene, {1, 1}, 10.0, RotateImage2d::InterpolationType::NEAREST_NEIGHBOR ); std::cout << "outputImage:" << result->toString();
polystyrene = ioformat.read_image(imagedev_data.get_image_path("polystyrene.tif")) result = imagedev.rotate_image_2d( polystyrene, [1, 1], 10.0, imagedev.RotateImage2d.NEAREST_NEIGHBOR ) print( "output_image:", str( result ) )
ImageView polystyrene = ViewIO.ReadImage( @"Data/images/polystyrene.tif" ); IOLink.ImageView result = Processing.RotateImage2d( polystyrene, new int[]{1, 1}, 10.0, RotateImage2d.InterpolationType.NEAREST_NEIGHBOR ); Console.WriteLine( "outputImage:" + result.ToString() );