상세 컨텐츠

본문 제목

[Computer Vision] _ Image Rotation

Computer Vision

by jii 2025. 6. 21. 14:22

본문

1. Introduction

This technical report provides an overview of an image rotation. The implementation uses Inverse Warping and two interpolation methods: Nearest Neighbor Interpolation and Bilinear Interpolation. The objective of this code is to rotate an image by a specified angle.

2. Explanation of code

The overview of key steps of the code:

  1. Define an enlarged, rotated image whose size is larger than original image.
  2. Perform Inverse Warping to map pixels from the rotated image back to the original image.
  3. Resample pixel values of original image(might be float) using interpolation.
  4. Copy the computed value to rotated image.

Detailed explanation of the code:

  • Compute rotated image size
float sq_row = ceil(row * sin(radian) + col * cos(radian));
float sq_col = ceil(col * sin(radian) + row * cos(radian));

 

→ ‘row’ and ‘col’ respectively indicates height and width of the original image, and ‘radian‘ indicates rotation angle. This code ensures that the rotated image has a bounding box that is large enough to contain all transformed pixels. The reason why we use the ceil function here is that new bounding box might have fractional pixel values, but since images are discrete domain, we should round up to ensure the rotated image is included in the new bounding box.

  • Inverse Warping
float x = (j - sq_col / 2) * cos(radian) - (i - sq_row / 2) * sin(radian) + col / 2;
float y = (j - sq_col / 2) * sin(radian) + (i - sq_row / 2) * cos(radian) + row / 2;

 

 

→ Rotation transformation is fundamentally performed around the origin. However, in digital images, the origin is located at the top-left corner (0,0). To perform rotation based on the center of the image, we need to shift the reference point to the center of the image. Therefore, we first move the center of the output image to the origin (0,0), apply transformation, and then restore the original center using a translation process.

 

(1) Rotation should occur in center. To accomplish this, we first translate each pixel (i, j) in the output image so that the center of the output image becomes the new origin (0,0).

⇒ j - sq_col / 2, i - sq_col / 2 This effectively shifts every pixel so that the center of the output image is now at (0,0).

 

(2) Apply the rotation matrix to rotate the point by an angle θ.

 

(3) After rotation, (x′,y′) must be shifted back to the original image center. This could be done by adding back the original center of the input image col2, row2.

  • Nearest Neighbor Interpolation
    • Nearest Neighbor Interpolation simply copy-and-paste the neighbor intensity value. So we need to convert float value x, y to nearest integer using round function.
    • In OpenCV, pixel access using Mat::at<T>(y,x) follows the matrix indexing order: the first argument refers to the row (y-axis) and the second to the column (x-axis). Therefore, although transformed coordinates are typically calculated as (x,y) in geometric space, they must be accessed as input.at<T>(y,x) in OpenCV to match the correct pixel location.
if (!strcmp(opt, "nearest")) {
					int x1 = round(x);
					int y1 = round(y);
					output.at<T>(i, j) = input.at<T>(y1, x1);
				}

  • Bilinear Interpolation
    • Bilinear interpolation computes target point (x,y) by taking a weighted average of the four surrounding nearest integer pixels.
else if (!strcmp(opt, "bilinear")) {
					int x1 = floor(x), x2 = ceil(x);
					int y1 = floor(y), y2 = ceil(y);

					if (x1 < 0) x1 = 0;
					if (x2 >= col) x2 = col - 1;
					if (y1 < 0) y1 = 0;
					if (y2 >= row) y2 = row - 1;

					T P11 = input.at<T>(y1, x1); // (x1, y1)
					T P21 = input.at<T>(y1, x2); // (x2, y1)
					T P12 = input.at<T>(y2, x1); // (x1, y2)
					T P22 = input.at<T>(y2, x2); // (x2, y2)

					float dx = x - x1;
					float dy = y - y1;

					output.at<T>(i, j) = (P11 * (1 - dx) * (1 - dy)) +
						(P21 * dx * (1 - dy)) +
						(P12 * (1 - dx) * dy) +
						(P22 * dx * dy);
				}

(1) First, it defines the four surrounding pixels by floor and ceil function, which respectively finds the lower bound and upper bound of (x, y).

(2) Each value should not be outside of the image, so we need to ensure that it is included in the range of [0, col-1] for x and [0, row-1] for y.

(3) We can define four surrounding pixels:

  • P11 : Top-left pixel (x1, y1)
  • P21 : Top-right pixel (x2, y1)
  • P12 : Bottom-left pixel (x1, y2)
  • P22 : Bottom-right pixel (x2, y2)

(4) Interpolation weights can be computed:

  • μ = dy = y - y1
  • λ = dx = x−x1

(5) Mathematical formula for bilinear interpolation can be written:

  • f(x1 ,y)=(1-μ) f(x1, y1)+μ f(x1, y2) ..(1)
  • f(x2, y)=(1-μ) f(x2, y1)+μ f(x2, y2) ..(2)
  • f(x, y)=(1-λ) f(x1, y)+λ f(x2, y) ..(3)

→ Now, f(x1,y) and f(x2,y) in equation (3) can be substituted with equation (1) and (2).

This is why the final code is :

(P11 * (1 - dx) * (1 - dy)) +(P21 * dx * (1 - dy)) +(P12 * (1 - dx) * dy) +(P22 * dx * dy);

3. Experimental results

  • Test Image: Lena (512x512)
  • Rotation Angles: 30°, 45°, 90°
  • Interpolation Methods: Nearest Neighbor, Bilinear

'Computer Vision' 카테고리의 다른 글

[Computer Vision] _ Image Stitching  (0) 2025.06.21
[RL] _ Intro to RL  (0) 2024.09.02
Computer Vision 2 _ Chap 07  (0) 2024.09.02
Computer Vision 2 _ Chap 06  (0) 2024.09.02
Computer Vision 2 _ Chap 05  (0) 2024.09.02

관련글 더보기

댓글 영역