You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从带倾斜角度的旋转图像中提取人脸区域?

问题根因

你当前使用的haarcascade_frontalface_default.xml是针对正向无偏转人脸训练的传统检测器,本身不支持旋转、大角度倾斜的人脸检测,因此无法处理倾斜人脸的提取需求。

可用解决方案

方案1:适配原有haar检测器,增加旋转遍历逻辑

如果不想更换检测器,可以对输入图像按固定步长旋转不同角度,每次旋转后执行人脸检测,检测到人脸后再将区域映射回原始图像裁剪即可,参考实现代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

def rotate_image(image, angle):
    h, w = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, angle, 1.0)
    rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
    return rotated, M

# 待检测的角度列表,可根据实际场景调整步长和范围
angles = [0, 10, -10, 20, -20, 30, -30, 45, -45, 60, -60, 90, -90, 180]
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")

image = cv2.imread('_img_1.png')
found_faces = []

for angle in angles:
    rotated_img, M = rotate_image(image, angle)
    gray = cv2.cvtColor(rotated_img, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.3,
        minNeighbors=3,
        minSize=(30, 30)
    )
    if len(faces) > 0:
        # 把检测到的框映射回原始图像
        for (x, y, w, h) in faces:
            # 旋转框的四个点
            points = np.array([[x, y], [x+w, y], [x, y+h], [x+w, y+h]], dtype='float32')
            # 求逆变换矩阵,映射回原图
            M_inv = cv2.invertAffineTransform(M)
            original_points = cv2.transform(points.reshape(-1, 1, 2), M_inv).reshape(-1, 2)
            # 取最小外接矩形
            x_min, y_min = np.min(original_points, axis=0).astype(int)
            x_max, y_max = np.max(original_points, axis=0).astype(int)
            # 裁剪人脸
            roi = image[y_min:y_max, x_min:x_max]
            found_faces.append(roi)
            cv2.rectangle(image, (x_min, y_min), (x_max, y_max), (0,255,0), 2)
        break

print(f"[INFO] 共检测到{len(found_faces)}张人脸")
for idx, face in enumerate(found_faces):
    cv2.imwrite(f'face_{idx}.jpg', face)
    plt.imshow(cv2.cvtColor(face, cv2.COLOR_BGR2RGB))
    plt.show()

cv2.imwrite('detected_result.jpg', image)

方案2:更换深度学习人脸检测器(更推荐,准确率和效率更高)

传统haar检测器精度低、适配场景少,直接换用支持多角度的深度学习人脸检测器效果更好,比如MTCNN,实现代码如下:
首先安装依赖:pip install mtcnn opencv-python matplotlib

import cv2
from mtcnn import MTCNN
import matplotlib.pyplot as plt
%matplotlib inline

detector = MTCNN()
image = cv2.imread('_img_1.png')
rgb_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = detector.detect_faces(rgb_img)

print(f"[INFO] 共检测到{len(results)}张人脸")
found_faces = []
for res in results:
    x1, y1, width, height = res['box']
    x2, y2 = x1 + width, y1 + height
    roi = image[y1:y2, x1:x2]
    found_faces.append(roi)
    cv2.rectangle(image, (x1, y1), (x2, y2), (0,255,0), 2)

for idx, face in enumerate(found_faces):
    cv2.imwrite(f'face_{idx}.jpg', face)
    plt.imshow(cv2.cvtColor(face, cv2.COLOR_BGR2RGB))
    plt.show()

cv2.imwrite('detected_result.jpg', image)

该方案天生支持最大±90度的旋转、俯仰、侧偏人脸检测,不需要额外做旋转遍历,针对你提供的示例图也能正常检测:
示例倾斜人脸图


内容的提问来源于stack exchange,提问作者Md. Rezwanul Haque

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:06:04