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

如何将NumPy数组图像的人脸矩形区域保存到变量中?

问题:提取图像局部区域到变量不符合预期

尝试从尺寸为(640,480,3)的numpy.ndarray图像中提取矩形框标记的区域到face_region变量,cv2.rectangle()能正常绘制并显示矩形,但提取的区域无法正确保留目标局部、或出现报错。相关代码如下:

def extract_face_region(image, landmarks):
    landmark_coords = np.array([(landmarks.part(i).x, landmarks.part(i).y) for i in [2, 14, 40, 41, 46, 47, 50, 52]])

    XLT = landmarks.part(14).x
    YLT = max(landmarks.part(40).y, landmarks.part(41).y, landmarks.part(46).y, landmarks.part(47).y)
    Wrect = landmarks.part(2).x - landmarks.part(14).x
    Hrect = min(landmarks.part(50).y, landmarks.part(52).y) - YLT

    if 0 <= XLT < image.shape[1] and 0 <= YLT < image.shape[0] and 0 <= XLT + Wrect <= image.shape[1] and 0 <= YLT + Hrect <= image.shape[0]:
        face_region = image[YLT:YLT+Hrect, XLT:XLT+Wrect, :]
    else:
        print("Region outside image limits.")
 
    cv2.rectangle(image, (int(XLT), int(YLT)), (int(XLT + Wrect), int(YLT + Hrect)), (255, 0, 0), 2)
    #cv2_imshow(image)
    cv2_imshow(face_region)  
    return face_region

解决建议

1. 统一处理坐标为整数

人脸关键点坐标通常是浮点数,直接用于numpy切片会导致错误或异常结果,先把所有坐标转为整数:

XLT = int(landmarks.part(14).x)
YLT = int(max(landmarks.part(40).y, landmarks.part(41).y, landmarks.part(46).y, landmarks.part(47).y))
XRT = int(landmarks.part(2).x)
YRB = int(min(landmarks.part(50).y, landmarks.part(52).y))

2. 避免负尺寸的矩形

如果关键点顺序导致XRT < XLT或YRB < YLT,计算出的宽高会是负数,numpy切片会返回空数组。强制修正坐标顺序确保宽高为正:

# 确保左x小于右x,上y小于下y
x1, x2 = min(XLT, XRT), max(XLT, XRT)
y1, y2 = min(YLT, YRB), max(YLT, YRB)
Wrect = x2 - x1
Hrect = y2 - y1

3. 初始化默认的face_region

当区域超出图像范围时,原代码中face_region未定义,直接调用cv2_imshow会抛出NameError。在else分支初始化空数组避免报错:

if 0 <= x1 < image.shape[1] and 0 <= y1 < image.shape[0] and 0 <= x2 <= image.shape[1] and 0 <= y2 <= image.shape[0]:
    face_region = image[y1:y2, x1:x2, :]
else:
    print("Region outside image limits.")
    face_region = np.array([])  # 初始化空数组

4. 优化切片显示逻辑

添加判断,仅当face_region有效时才显示,避免空数组报错:

if face_region.size > 0:
    cv2_imshow(face_region)

修正后的完整代码

def extract_face_region(image, landmarks):
    # 提取关键点坐标并转为整数
    XLT = int(landmarks.part(14).x)
    YLT = int(max(landmarks.part(40).y, landmarks.part(41).y, landmarks.part(46).y, landmarks.part(47).y))
    XRT = int(landmarks.part(2).x)
    YRB = int(min(landmarks.part(50).y, landmarks.part(52).y))

    # 修正坐标顺序,确保矩形宽高为正
    x1, x2 = min(XLT, XRT), max(XLT, XRT)
    y1, y2 = min(YLT, YRB), max(YLT, YRB)

    # 提取目标区域
    if 0 <= x1 < image.shape[1] and 0 <= y1 < image.shape[0] and 0 <= x2 <= image.shape[1] and 0 <= y2 <= image.shape[0]:
        face_region = image[y1:y2, x1:x2, :]
    else:
        print("Region outside image limits.")
        face_region = np.array([])
 
    cv2.rectangle(image, (x1, y1), (x2, y2), (255, 0, 0), 2)
    if face_region.size > 0:
        cv2_imshow(face_region)  
    return face_region

内容的提问来源于stack exchange,提问作者leonardo20

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 01:57:37