使用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在鼻子和眼睛轴上旋转图像的主要内容,如果未能解决你的问题,请参考以下文章
人脸检测进阶:使用 dlibOpenCV 和 Python 检测眼睛鼻子嘴唇和下巴等面部五官
使用matlab机器视觉工具箱实现人脸特征的检测和定位,识别并标注眉毛,眼睛,鼻子,嘴巴