[网络资源整合版] 使用 OpenCV 和 Python 对图片进行旋转

更新:

def rotate_bound_white_bg(image, angle):
    (h, w) = image.shape[:2]
    (cX, cY) = (w // 2, h // 2)
    # -angle位置参数为角度参数负值表示顺时针旋转; 1.0位置参数scale是调整尺寸比例(图像缩放参数),建议0.75
    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
    # compute the new bounding dimensions of the image
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))
    # adjust the rotation matrix to take into account translation
    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY

    # perform the actual rotation and return the image
    # borderValue 缺失背景填充色彩,此处为白色,可自定义
    return cv2.warpAffine(image, M, (nW, nH), borderValue=(0, 0, 0))

 原始:

def rotate_about_center(src, angle, scale=1.):
    w = src.shape[1]
    h = src.shape[0]
    rangle = np.deg2rad(angle)  # angle in radians
    # now calculate new image width and height
    nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))*scale
    nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))*scale
    # ask OpenCV for the rotation matrix
    rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, scale)
    # calculate the move from the old center to the new center combined
    # with the rotation
    rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
    # the move only affects the translation, so update the translation
    # part of the transform
    rot_mat[0,2] += rot_move[0]
    rot_mat[1,2] += rot_move[1]
    return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)

从原始图像的中心到目标图像的中心,在旋转中的仿射变换必须结合 仿射变换的平移。一个在平面中(2D)的仿射变换是一个 2x2 的矩阵 A 和一个平移的向量 a - 它取得原始点 p = (x,y)到目标:Ap + a. 结合了两次变换 Ap + a 和 Bp+b,先做 A 然后是 B,软后得到了 B (Ap + a)+ b -- 另一个与矩阵 BA 和向量 Ba + b 的仿射变换。在此情况下,我们正在把旋转功能与平移合并。作为相似变换的平移具有 2x2 矩阵 I 与运动矢量 m 的特征,所以,以 Ip + m 表示,我们想首先平移到新的中心,饭后旋转它,这样,在应用 Ip + m 后我们旋转 Rp + r,产生 Rp + Rm + r,这解释了为什么我们不得不只增加两个系数。

更新:

第一个的仿射变换效果比第二个更好,第二个的形变太大,第一个是中心仿射,第二个是原点仿射。

posted @ 2022-03-08 19:39  E-CorE  阅读(79)  评论(0)    收藏  举报