使用opencv在鼻子和眼睛轴上旋转图像

rotate a image on the nose and eye axis with opencv

我有以下带有眼睛和噪声点的图像。图片中的人倾斜度很小,我想将其归一化。我用 dlib 标记了地标,所以我可以计算倾斜度。

现在,我怎样才能简单地旋转整个图像,那个家伙是直的?

LEFT_EYE: [(274, 269), (286, 259), (302, 258), (317, 268), (302, 271), (286, 272)]
RIGHT_EYE : [(388, 264), (401, 254), (417, 252), (431, 261), (419, 265), (403, 265)]
NOSE: [(352, 257), (353, 278), (354, 297), (354, 319)]

作为一个想法,x轴上的鼻点是352、353、354、354。理论上,如果我进行矩阵变换,将所有x点更改为352,噪声将呈直线.

我觉得可以用矩阵变换,噪声点或者眼点做向量变换。但是我需要一个方法,这个怎么解决。

首先对鼻子点做线性拟合,用斜率求角度。为此,请切换 x 值和 y 值,使垂直向上的角度为 0 度(另外,当鼻子几乎垂直开始时,您会获得更好的贴合度)。

# Nose points
nose =  np.array([(352, 257), (353, 278), (354, 297), (354, 319)])

# Linear fit with x- and y-values switched
m,b = np.polyfit(nose[:,1], nose[:,0], 1)

# Angle in radians
angle = np.arctan(m)

接下来可以使用opencv来get a rotation matrix. If the center of rotation doesn't matter, you can just rotate around the center of the image. But below I rotate it around the top of the nose so the points sit vertically along the x=352 line if you do want that. Finally, use the rotation matrix to rotate the image with cv2.warpAffine.

# Get rotation matrix
rot_mat = cv2.getRotationMatrix2D(tuple(nose[0]), -angle*180./np.pi, 1)

# Rotate image
dims = tuple(img.shape[:2][::-1])
rotated_image = cv2.warpAffine(img, rot_mat, dims)

这是生成的图像:

假设您知道旋转的度数(例如,从 0 度到 360 度)。

下面的函数只做一件事:旋转图像而不丢失原始输入的任何像素。

参数为(1)原图; (2)旋转度数。 输出应该是旋转后的图像。

def rotate_bound(image, angle):
    # grab the dimensions of the image and then determine the
    # center
    (h, w) = image.shape[:2]
    (cX, cY) = (w // 2, h // 2)

    # grab the rotation matrix (applying the negative of the
    # angle to rotate clockwise), then grab the sine and cosine
    # (i.e., the rotation components of the matrix)
    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
    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
    return cv2.warpAffine(image, M, (nW, nH))

实现来自很棒的博客“Rotate image (correctly) with OpenCV and Python”。我相信你可以在那里找到更多的细节和有用的知识。

玩得开心。