(11) Image geometric transformation

1. Affine transformation

(1) Scaling: The image size is enlarged or reduced according to the specified ratio, cv2.resize(), cv.INTER_AREA, cv.INTER_CUBIC, cv.INTER_LINEAR

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg')
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
#OR
height, width = img.shape[:2]
res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)

(2) Translation: Move all the points in the image horizontally or vertically according to the specified translation amount, and input the translation matrix M as warpAffine()

import numpy as np
import cv2 as cv
img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
M = np.float32([[1,0,100],[0,1,50]])
dst = cv.warpAffine(img,M,(cols,rows))

(3) Rotation: rotate the image around a specified point by a certain angle, and rotate the rotation matrix of θ

 Rotate while scaling around a center point:

img = cv.imread('messi5.jpg',0)
rows,cols = img.shape
M = cv.getRotationMatrix2D((cols/2,rows/2),90,1)
dst = cv.warpAffine(img,M,(cols,rows))

(4)  Affine transformation: 3 pairs of points are required, cv.getAffineTransform gets a 2*3 matrix

img = cv.imread('drawing.png')
rows,cols,ch = img.shape
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv.getAffineTransform(pts1,pts2)
dst = cv.warpAffine(img,M,(cols,rows))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

2. Projection transformation

 4 pairs of points are required , of which 3 pairs of points are not collinear, cv.getPerspectiveTransform gets a 3*3 matrix

img = cv.imread('sudoku.png')
rows,cols,ch = img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv.getPerspectiveTransform(pts1,pts2)
dst = cv.warpPerspective(img,M,(300,300))
plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

3. Image transformation

The input image is transformed into the output image after affine transformation. Note that integer coordinates in the output image are transformed to non-integer coordinates in the original image, so grayscale values ​​must be interpolated.

 A pixel in the output image has been transformed back into the input image. Note that the center point of this pixel after the transformation is located between the center points of the four adjacent pixels, which is a non-integer position. The simplest and fastest interpolation method is to first round the non-integer coordinates of the converted pixel center to find the closest one of the center positions of the four pixel points adjacent to this coordinate, and then convert the nearest neighbor in the input image. The gray value of the pixel at the position is regarded as the gray value of the corresponding pixel in the output image. It is called nearest field interpolation. Bilinear interpolation: Calculate the vertical and horizontal distances from the transformed coordinates to the center points of four adjacent pixels. Note that these calculated distance values ​​are between 0 and 1. Then, the weights occupied by different grayscale values ​​are calculated according to the distance values ​​to obtain the result of bilinear interpolation.

 

for (size_t n = 0; n < neighbors; n++) {
  float x = static_cast<float>(-radius) *
            sin(2.0 * CV_PI * n / static_cast<float>(neighbors));
  float y = static_cast<float>(radius) *
            cos(2.0 * CV_PI * n / static_cast<float>(neighbors));
  //下取整或上取整
  int fx = static_cast<int>(floor(x));
  int fy = static_cast<int>(floor(y));
  int cx = static_cast<int>(ceil(x));
  int cy = static_cast<int>(ceil(y));

  // fraction part
  float tx = x - fx;
  float ty = y - fy;
  //设置四个点的插值权重
  float w1 = (1 - tx) * (1 - ty);
  float w2 = tx * (1 - ty);
  float w3 = (1 - tx) * ty;
  float w4 = tx * ty;
  for (int i = radius; i < src.rows - radius; i++)
    for (int j = radius; j < src.cols - radius; j++) {
      float t =
          w1 * src.at<_Tp>(i + fy, j + fx) + w2 * src.at<_Tp>(i + fy, j + cx) +
          w3 * src.at<_Tp>(i + cy, j + fx) + w4 * src.at<_Tp>(i + cy, j + cx);
      dst.at<int>(i - radius, j - radius) +=
          ((t > src.at<_Tp>(i, j)) || (std::abs(t - src.at<_Tp>(i, j)) <
                                       std::numeric_limits<float>::epsilon()))
          << n;
    }
}

4. Polar coordinate transformation

Polar transformations are often used to correct circular objects in images or objects contained in rings

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324082392&siteId=291194637