The rotation of the image in the application of linear algebra

When it comes to linear algebra, the teacher seems to only tell us that matrices have a wide range of applications and are very important. But
after one semester, everyone seems to only do the questions and don't know how to use the matrix. At the beginning, I was also very confused. The knowledge I learned seemed to have nothing to do with the actual application. For example, I heard people say that the image matrix can be rotated. But how to rotate and how to rotate has never been understood. Although the Internet Baidu only gave the formula for image rotation, but did not give a specific explanation. After some research, I still understand the whole process of image rotation. Here I share it with you, hoping to help you.

Image Rotation Steps

First of all, everyone must first understand the steps of image rotation. Only by knowing what you are doing in each step will you not be confused:
let's read a picture first, imagine putting the picture in a coordinate system, the upper left corner of the picture and the coordinates The origin coincides, and the index of the image matrix at this time coincides with the coordinates (x, y) in the coordinate system. Then, each (x, y) coordinate corresponding to the picture is rotated at a certain angle to obtain (x1, y1). At this time, some coordinates x1, y1 may be negative values. Such negative values ​​are in the index of the matrix. not scientific. So we need to change the negative value into a positive value, which is equivalent to shifting to the quadrant of the positive value, and the coordinates after the shift are (x2, y2). Finally, the pixel value is obtained from the original image matrix according to the index (x, y), and assigned to the corresponding matrix index (x2, y2). This is done.
Only with pictures and texts can we better understand, let’s look at the picture below:
insert image description here

Implementation Difficulties

Let's talk about how the rotation matrix comes from and what it looks like.
Suppose a point is (x, y), and the rotation angle is θ \thetaθ . It is difficult to express the rotation in the rectangular coordinate system, we express it in the polar coordinate system:x 2 + y 2 = r 2 x = r cos ⁡ α y = r sin ⁡ α x^2+y^2 = r^2\qquad x = r\cos\alpha \qquad y = r\sin\alphax2+y2=r2x=rcosay=rsinα
, the rotated coordinates are:x = r cos ⁡ ( α − θ ) y = r sin ⁡ ( α − θ ) x = r\cos(\alpha-\theta) \qquad y = r\sin(\alpha -\theta)x=rcos ( ai )y=rsin ( aθ )
Equations:x 1 = x cos ⁡ θ + y sin ⁡ θ y 1 = y cos ⁡ θ − x sin ⁡ θ x1 = x\cos\theta+y\sin\theta \qquad y1 = y\ cos\theta-x\sin\thetax 1=xcosi+ysiniy 1=ycosixsinLet θ
be a continuous variable and have a smooth equation:
[ xy ] ∗ [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] = [ x 1 y 1 ] \begin{bmatrix}x & . y\\ \end{bmatrix}*\begin{bmatrix}\cos\theta&-\sin\theta\\\sin\theta&\cos\theta\\\end{bmatrix}=\begin{bmatrix}x1 & y1\\\end {bmatrix}[xy][cosisinisinicosi]=[x 1y 1]
The above rotation formula is only theoretical, but it needs to be further modified in practice. The general rotation is to rotate the center of the image by default, so we need to move the center of the image to the origin first, then rotate, and finally move it to the original position. (W, h here represent the length and width of the image)
[ xy 1 ] ∗ [ 1 0 0 0 1 0 − w / 2 − h / 2 1 ] ∗ [ cos ⁡ θ − sin ⁡ θ 0 sin ⁡ θ cos ⁡ θ 0 0 0 1 ] ∗ [ 1 0 0 0 1 0 w / 2 h / 2 1 ] = [ x 1 y 1 1 ] \begin{bmatrix}x & y&1\\ \end{bmatrix}*\begin{ bmatrix}1&0&0\\0&1&0\\-w/2&-h/2&1\\ \end{bmatrix}*\begin{bmatrix}\cos\theta&-\sin\theta&0\\ \sin\theta&\cos\theta&0\\ 0&0&1\\ \end{bmatrix}*\begin{bmatrix}1&0&0\\0&1&0\\w/2&h/2&1\\ \end{bmatrix}=\begin{bmatrix}x1 & y1&1\\ \end{bmatrix}[xy1] 10w/201h/2001 cosisini0sinicosi0001 10w/201h/2001 =[x 1y 11]
within the equation
[ xy 1 ] ∗ [ cos ⁡ θ − sin ⁡ θ 0 sin ⁡ θ cos ⁡ θ 0 w / 2 − w / 2 ∗ cos ⁡ − h / 2 ∗ sin ⁡ w / 2 ∗ sin ⁡ − h / 2 ∗ cos ⁡ + h / 2 1 ] = [ x 1 y 1 1 ] \begin{bmatrix}x & y&1\\ \end{bmatrix}*\begin{bmatrix}\cos\theta&-\ sin\theta&0\\ \sin\theta&\cos\theta&0\\w/2-w/2*\cos-h/2*\sin&w/2*\sin-h/2*\cos+h/2&1\\ \end{bmatrix}=\begin{bmatrix}x1 & y1&1\\\end{bmatrix}[xy1] cosisiniw/2w/2cosh/2sinsinicosiw/2sinh/2cos+h/2001 =[x 1y 11]
This is the formula we will use in programming.
So far, our core work has been completed, and we can implement it with code below.

Code

There will be some key points in the implementation process, and I have also made notes

import cv2
import numpy as np

#创建用于图像坐标转换的矩阵
def create_rotation_matrix(angle,w,h):
    cos = np.cos(np.deg2rad(angle))
    sin = np.sin(np.deg2rad(angle))
    matrix = np.array([[cos,-sin,0],[sin,cos,0],[w-w*cos-h*sin,w*sin-h*cos+h,1]])
    return matrix

#图像旋转
def rotation_image(image,matrix,background = 0):
    #获取图像的大小
    w,h,z = image.shape
    
    #创建旋转图像的矩阵的变量名
    rotation_image = None
    
    #创建图像坐标矩阵,这里新创建的矩阵相当于图纸,而旋转后的坐标代表要在纸上画图的位置
    coordinate = np.array([[i,j,1] for i in range(w) for j in range(h)],dtype = np.int16)

    #矩阵旋转
    rotation_coordinate = np.dot(coordinate,matrix)
    #将矩阵由浮点型转换为整数型,矩阵的索引需要整数。
    rotation_coordinate = rotation_coordinate.astype(np.int16)
    
    #将对应坐标像素赋值,此方法是将超出图像背景的部分进行了裁剪
    if background == 0:
        
        #创建旋转图像的矩阵
        rotation_image = np.zeros((w,h,z),dtype = np.uint8)
        
        #循环将相对应的像素进行赋值
        for i in range(coordinate.shape[0]):
            x,y,_ = coordinate[i]
            rot_x,rot_y,_ = rotation_coordinate[i]
            
            if rot_x<0 or rot_x>=w or rot_y<0 or rot_y>=h:
                #对于超出旋转矩阵范围的坐标点,不做处理
                pass
            else:
                rotation_image[rot_x,rot_y,:] = image[x,y,:]
    #非零代表不裁剪
    else:
        #找出坐标矩阵中最小的x和y
        min_coor = np.min(rotation_coordinate,axis = 0)
        
        #让坐标矩阵的所有x和y减去对应的最小x和y,这是坐标位于第一象限(都为正直)
        rotation_coordinate = rotation_coordinate-min_coor
        
        #再找出坐标矩阵的最大的x和y,作为rotation_image矩阵的大小
        max_coor = np.max(rotation_coordinate,axis = 0)

        rotation_image = np.zeros((max_coor[0]+1,max_coor[1]+1,z),dtype = np.uint8)
        
        #像素赋值
        for i in range(coordinate.shape[0]):
            x,y,_ = coordinate[i]
            rot_x,rot_y,_ = rotation_coordinate[i]
            rotation_image[rot_x,rot_y,:] = image[x,y,:]
     
    return rotation_image
        

if __name__ == '__main__':
    #读取图像
    image = cv2.imread(r'C:\Users\Administrator\Desktop\1.png')
    #image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    w,h,_= image.shape
    
    #注意这里传入的旋转点w,h不能直接传入的是w,h = image.shape
    #传入的应该是0至(w-1)和0至(h-1)
    matrix = create_rotation_matrix(angle=-45,w =w/2,h = h/2)
    
    #background为0时代表的是旋转后的图像与原图像大小相同相当于裁剪了图像,
    #传入其他数值则为显示完整的旋转图像 
    rotation_image = rotation_image(image,matrix,background = 1)

    cv2.imshow('image',image)
    cv2.imshow('rotation_image',rotation_image)
    cv2.waitKey()
    cv2.destroyAllWindows()

Effect screenshot:
insert image description here
the left is the original image, and the right is the rotated image.

Summarize

I believe you have seen small black dots in the rotated image. This is because the coordinate values ​​of the rotated image are generally decimals, but we directly convert them to integers, which will result in no pixels in the rotated position. There may be other reasons too.
This rotation method is forward pixel value transfer, and another is backward pixel value transfer (find the corresponding pixel value in the original image according to the coordinates after rotation) plus a pixel interpolation method can solve the above problem.
This article mainly wants to talk about the use of matrices. For solving the problem of small black spots after rotation above, wait until the next article to explain it.

Guess you like

Origin blog.csdn.net/m0_59151709/article/details/130921820