cv2&numpy&tobeadded

  1. 矩阵乘法
    • np.dot(A,B):真正的矩阵乘法
    • np.multiply(A,B) & np重载的*:element-wise product,矩阵中对应元素相乘
    • cv的A.dot(B) & cv重载的*:真正的矩阵乘法
    • cv的A.mul(B) :element-wise product,矩阵中对应元素相乘
  1. 图像旋转

    通过仿射矩阵cv2.getRotationMatrix2D和仿射变换函数cv2.warpAffine来实现

    • src:输入图像

    • M:变换矩阵

    • dsize:输出图像的大小(基于图像原点裁剪)

    • flags:插值方法

    • borderMode:边界像素模式

    • borderValue:边界填充值,默认为0

      cv2.getRotationMatrix2D(center, angle, scale):返回一个2x3的变换矩阵

    • center:旋转中心

    • angle:旋转角度,正值是逆时针旋转
    • scale:缩放因子

      cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])):返回变换后的图像

    • src:输入图像

    • M:变换矩阵

    • dsize:输出图像的大小(基于图像原点裁剪)

    • flags:插值方法

    • borderMode:边界像素模式

    • borderValue:边界填充值,默认为0

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      def rotate_img(angle, img, interpolation=cv2.INTER_LINEAR, points=[]):
      h, w = img.shape
      rotataMat = cv2.getRotationMatrix2D((w/2, h/2), math.degrees(angle), 1)
      # rotate_img1: 输出图像尺寸不变,超出原图像部分被cut掉
      rotate_img1 = cv2.warpAffine(img, rotataMat, dsize=(w, h), flags=interpolation, borderMode=cv2.BORDER_CONSTANT, borderValue=0)
      # rotate_img2: 输出图像尺寸变大,保留超出原图像部分,新的坐标原点保证旋转中心仍旧位于图像中心
      new_h = int(w*math.fabs(math.sin(angle)) + h*math.fabs(math.cos(angle)))
      new_w = int(h*math.fabs(math.sin(angle)) + w*math.fabs(math.cos(angle)))
      rotataMat[0, 2] += (new_w - w) / 2
      rotataMat[1, 2] += (new_h - h) / 2
      rotate_img2 = cv2.warpAffine(img, rotataMat, dsize=(new_w, new_h), flags=interpolation, borderMode=cv2.BORDER_CONSTANT, borderValue=0)

      # 坐标点的变换
      rotated_points = []
      for point in points:
      point = rotataMat.dot([[point[0]], [point[1]], [1]])
      rotated_points.append((int(point[0]), int(point[1])))

      return rotate_img2, rotated_points

      使用tips:

    • 如果不修改仿射变换矩阵的平移参数,坐标原点的位置不发生改变

    • dsize指定的输出图像是从原点位置开始裁剪

    • 坐标点的变换满足公式:

  1. np.meshgrid(*xi,**kwargs)

    这个函数神他妈坑,作用是Return coordinate matrices from coordinate vectors. Make N-D coordinate arrays for vectorized evaluations of N-D scalar/vector fields over N-D grids, given one-dimensional coordinate arrays x1, x2,…, xn. 但是尝试一下会发现:

    1
    2
    3
    4
    5
    x = np.arange(0,10,1)
    y = np.arange(0,20,1)
    z = np.arange(0,30,1)
    x, y, z= np.meshgrid(x, y, z)
    print(x.shape) # (20, 10, 30)

    xy轴坐标是反过来的,这是因为optional args里面有一个indexing:

    indexing : {‘xy’, ‘ij’}, Cartesian (‘xy’, default) or matrix (‘ij’) indexing of output.

    我们想要得到的坐标系和输入的轴一一对应,得指定参数indexing='ij'

    1
    2
    3
    4
    5
    x = np.arange(0,10,1)
    y = np.arange(0,20,1)
    z = np.arange(0,30,1)
    x, y, z= np.meshgrid(x, y, z, indexing='ij')
    print(x.shape) # (10, 20, 30)

    还有一个参数sparse,因为每根轴的坐标都是复制的,所以可以稀疏存储,此时函数返回值变化:

    sparse : bool, If True a sparse grid is returned in order to conserve memory. Default is False.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    x = np.arange(0,10,1)
    y = np.arange(0,20,1)

    xx, yy = np.meshgrid(x, y)
    print(xx) # a 20x10 list

    xx, yy = np.meshgrid(x, y, sparse=True)
    print(xx) # a 1*10 list
    print(yy) # a 20*1 list
    # 所以整体上还是个20*10的矩阵

    二维可视化:

    1
    2
    3
    4
    5
    import matplotlib.pyplot as plt

    z = xx**2 + yy**2 # xx和yy既可以是dense convervation也可以是sparse convervation
    h = plt.contourf(x,y,z)
    plt.show()
  1. np.tile(A,reps)

    这个函数挺有用的,把数组沿着指定维度复制,比stack、concat啥的都优雅,能自动创建新的维度

    • A:array_like, The input array.
    • reps:array_like, The number of repetitions of A along each axis.
  1. np.reshape(a, newshape, order=’C’)

    这个函数贼常用,但是一般用于二维的时候没考虑重组顺序这件事

    • order: {‘C’, ‘F’, ‘A’}, optional,简单理解,reshape的通用实现方式是先将真个array拉直,然后依次取数据填入指定维度,C是从最里面的维度开始拉直&构造,F是从最外面的维度开始拉直&构造,A for auto

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      a = np.arange(6)
      array([0, 1, 2, 3, 4, 5])

      # C-like index ordering
      np.reshape(a, (2, 3))
      array([[0, 1, 2],
      [3, 4, 5]])

      # Fortran-like index ordering
      np.reshape(a, (2, 3), order='F')
      array([[0, 4, 3],
      [2, 1, 5]])
    • tf和keras里面也有reshape,是没有order参数的,默认是’C’