You need to enable JavaScript to run this app. 如何裁剪或叠加人脸面罩图像的多边形区域以匹配输出规格
优惠活动
大模型
产品
解决方案
定价
更多

如何裁剪或叠加人脸面罩图像的多边形区域以匹配输出规格

人脸面罩图像处理方案

需求说明

共有3张样本图像用于参考,需将输入的人脸面罩图像处理为指定的输出形态:

  • 样本输入图像:输入图像
  • 上色后的输入图像:上色后输入图像
  • 样本输出图像:样本输出图像

原有方案问题

此前采用固定阈值二值化+面积阈值筛选轮廓的处理逻辑,未能得到预期输出,原有实现代码如下:

import cv2
import matplotlib.pyplot as plt

face_mask = cv2.imread('data/mask5.png')
face_mask = cv2.cvtColor(face_mask, cv2.COLOR_BGR2RGB)
gray_mask = cv2.cvtColor(face_mask, cv2.COLOR_RGB2GRAY)

# 二值化阈值处理
_, binary = cv2.threshold(gray_mask, 225, 255, cv2.THRESH_BINARY_INV)

contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_list = []
for c in contours:
    area = cv2.contourArea(c)
    if area > 2000:
        print(area)
        contour_list.append(c)

# 绘制轮廓
img = cv2.drawContours(face_mask, contour_list, -1, (0, 255, 0), 2)
plt.imshow(img)
plt.show()

原有方案的核心问题是固定灰度阈值二值化受光照、背景干扰影响大,仅靠面积筛选轮廓无法排除背景中大块的非面罩区域,无法精准定位面罩范围。

最优处理方案

推荐采用颜色空间分割+形态学预处理+多条件轮廓筛选的组合方案,处理步骤如下:

  1. 颜色空间转换:将原图从RGB转为HSV颜色空间,根据面罩的颜色范围设置阈值生成初始掩码,相比灰度二值化能精准区分面罩、人脸皮肤和背景区域。
  2. 掩码优化:对初始掩码做开运算+闭运算的形态学处理,消除小噪点、填补面罩区域的空洞,得到完整的掩码区域。
  3. 多条件轮廓筛选:对优化后的掩码提取轮廓,除了面积阈值,额外增加外接矩形宽高比的筛选条件,排除背景中符合面积但不符合面罩形态的干扰轮廓。
  4. 输出裁剪:取筛选后的最大轮廓的外接矩形,裁剪原图对应区域后,用掩码将区域外的背景替换为白色/透明,得到和样本一致的输出。

优化后实现代码

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

face_mask = cv2.imread('data/mask5.png')
face_mask_rgb = cv2.cvtColor(face_mask, cv2.COLOR_BGR2RGB)
hsv = cv2.cvtColor(face_mask_rgb, cv2.COLOR_RGB2HSV)

# 面罩颜色阈值(可根据实际样本调整HSV范围,这里以上色后的蓝色面罩为例)
lower_mask = np.array([90, 50, 50])
upper_mask = np.array([130, 255, 255])

# 生成初始掩码
mask = cv2.inRange(hsv, lower_mask, upper_mask)

# 形态学处理优化掩码
kernel = np.ones((5,5), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

# 提取轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 多条件筛选轮廓
max_contour = None
max_area = 0
for c in contours:
    area = cv2.contourArea(c)
    if area < 2000:
        continue
    x,y,w,h = cv2.boundingRect(c)
    aspect_ratio = w / h
    # 面罩宽高比范围可根据样本调整
    if 1.2 <= aspect_ratio <= 2.5 and area > max_area:
        max_area = area
        max_contour = c

# 裁剪输出
if max_contour is not None:
    x,y,w,h = cv2.boundingRect(max_contour)
    output = face_mask_rgb[y:y+h, x:x+w]
    # 可选:将区域外背景设为白色
    output_mask = mask[y:y+h, x:x+w]
    output[output_mask == 0] = [255,255,255]

    plt.imshow(output)
    plt.axis('off')
    plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 14:54:01