要打破它:
我有点坚持第3步,我认为可以通过仿射变换完成?但是我完全被第4步难倒,我不知道如何实现它。
如果您需要我提供密码,请告诉我!
编辑:所以在看完@Gal Dreiman的回答之后,我能够完美地将脸部居中,以便在我的图像中心找到蓝点。虽然当我实施他的答案的第二部分时,我最终得到了这样的东西:
我看到这些点已被转换到正确的位置,但它并不是我所希望的结果,因为它非常显着。有什么想法吗?
编辑2:
切换中心点的x,y坐标后,这就是我得到的:
答案 0 :(得分:7)
正如我在第3部分看到的那样,最简单的方法是:
在图片中找到面孔:
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
对于每张脸,计算中点:
for (x, y, w, h) in faces:
mid_x = x + int(w/2)
mid_y = y + int(h/2)
仿射变换图像使您已计算的蓝点居中:
height, width = img.shape
x_dot = ...
y_dot = ...
dx_dot = int(width/2) - x_dot
dy_dot = int(height/2) - y_dot
M = np.float32([[1,0,dx_dot],[0,1,dy_dot]])
dst = cv2.warpAffine(img,M,(cols,rows))
希望它有用。
修改:
关于第4节: 为了拉伸(调整大小)图像,您所要做的就是执行仿射变换。为了找到变换矩阵,我们需要输入图像中的三个点及其在输出图像中的相应位置。
p_1 = [eyes_x, eye_y]
p_2 = [int(width/2),int(height/2)] # default: center of the image
p_3 = [mouth_x, mouth_y]
target_p_1 = [eyes_x, int(eye_y * 0.45)]
target_p_2 = [int(width/2),int(height/2)] # don't want to change
target_p_3 = [mouth_x, int(mouth_y * 0.75)]
pts1 = np.float32([p_1,p_2,p_3])
pts2 = np.float32([target_p_1,target_p_2,target_p_3])
M = cv2.getAffineTransform(pts1,pts2)
output = cv2.warpAffine(image,M,(height,width))
清除问题:
eye_x
/ eye_y
是眼睛中心的位置。mouth_x
/ mouth_y
,适用于口中心。target_p_1/2/3
是目标点。编辑2: 我发现你遇到了麻烦,我希望这次我的建议对你有用:
还有另一种我能想到的方法。您可以通过指向4个点对图像执行“裁剪”,让它们定义为包裹脸部的4个点,并根据新位置更改图像透视:
up_left = [x,y]
up_right = [...]
down_left = [...]
down_right = [...]
pts1 = np.float32([up_left,up_right,down_left,down_right])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))
所以你要做的就是定义这4点。我的建议是,计算脸部周围的纹路(你已经做过),之后将delta_x
和delta_y
(或减去)加到坐标上。