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

Posted

技术标签:

【中文标题】使用opencv在鼻子和眼睛轴上旋转图像【英文标题】:rotate a image on the nose and eye axis with opencv 【发布时间】:2019-04-29 14:11:08 【问题描述】:

我有以下带有眼睛和噪点的图像。图片中的那个人有一个最小的倾斜,我想把它标准化。我已经用 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,噪声将是一条直线。

我认为它可以通过矩阵变换来完成,而噪声或眼点作为矢量变换。但我需要一种方法,如何解决。

【问题讨论】:

是的,可以通过旋转矩阵来完成。这个概念是正确的。 【参考方案1】:

首先,对鼻子点进行线性拟合,并使用斜率来找到角度。为此,请切换 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。如果旋转中心无关紧要,您可以围绕图像中心旋转。但在下面,我将它围绕鼻子的顶部旋转,这样如果你想要的话,这些点就会沿着 x=352 线垂直放置。最后,使用旋转矩阵对图片进行旋转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)

这是生成的图像:

【讨论】:

【参考方案2】:

假设您知道旋转角度(例如,从 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”。我相信你可以在那里找到更多的细节和有用的学习。

玩得开心。

【讨论】:

以上是关于使用opencv在鼻子和眼睛轴上旋转图像的主要内容,如果未能解决你的问题,请参考以下文章

我将如何通过仿射变换在opencv中实现这一点?

人脸检测进阶:使用 dlibOpenCV 和 Python 检测眼睛鼻子嘴唇和下巴等面部五官

在opencv中创建透明图像

使用matlab机器视觉工具箱实现人脸特征的检测和定位,识别并标注眉毛,眼睛,鼻子,嘴巴

人脸检测实战终极:使用 OpenCV 和 Python 进行人脸对齐

OpenCV3计算机视觉+Python