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

iOS中CIPersonSegmentation蒙版位置偏移,如何正确定位?

解决CIPersonSegmentation蒙版与原图Extent不匹配的错位问题

原图:
原图

错误效果:
蒙版错位效果

使用CIPersonSegmentation生成蒙版替换背景时出现蒙版错位,本质是该滤镜输出的蒙版尺寸(extent)与原图不一致:原图extent为(0.0, 0.0, 2882.0, 1300.0),蒙版输出为(0.0, 0.0, 2016.0, 1300.0)。直接裁剪蒙版无法解决尺寸差带来的错位,必须将蒙版缩放至原图尺寸并对齐。

修正后的代码

if let image = UIImage(named: "demo9"), let edited = applyPersonFilter(to: image) {
    imageView.image = edited
}

func applyPersonFilter(to image: UIImage) -> UIImage? {
    guard let ciImage = CIImage(image: image) else { return nil }
    
    let context = CIContext(options: nil)
    
    // 生成人物分割蒙版
    let personMaskFilter = CIFilter(name: "CIPersonSegmentation", parameters: [
        kCIInputImageKey: ciImage,
        "inputQualityLevel": 0
    ])
    guard let rawMask = personMaskFilter?.outputImage else { return nil }
    
    // 计算蒙版缩放比例,匹配原图尺寸
    let scaleRatio = ciImage.extent.width / rawMask.extent.width
    // 使用Lanczos缩放保证蒙版清晰度
    let scaleFilter = CIFilter(name: "CILanczosScaleTransform")!
    scaleFilter.setValue(rawMask, forKey: kCIInputImageKey)
    scaleFilter.setValue(scaleRatio, forKey: kCIInputScaleKey)
    scaleFilter.setValue(0.0, forKey: kCIInputAspectRatioKey)
    
    guard let alignedMask = scaleFilter.outputImage else { return nil }
    
    // 生成青色背景层
    let solidColorFilter = CIFilter(name: "CIConstantColorGenerator")!
    solidColorFilter.setValue(CIColor.cyan, forKey: kCIInputColorKey)
    guard let cyanBackground = solidColorFilter.outputImage?.cropped(to: ciImage.extent) else { return nil }
    
    // 蒙版混合原图与背景
    let blendFilter = CIFilter(name: "CIBlendWithRedMask", parameters: [
        kCIInputImageKey: ciImage,
        kCIInputBackgroundImageKey: cyanBackground,
        kCIInputMaskImageKey: alignedMask
    ])
    
    guard let outputImage = blendFilter?.outputImage else { return nil }
    
    guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil }
    return UIImage(cgImage: cgImage)
}

核心修复点

  1. 计算缩放比例:根据原图和蒙版的宽度差值计算缩放倍数,确保蒙版尺寸和原图完全匹配;
  2. Lanczos缩放蒙版:相比基础的仿射变换,CILanczosScaleTransform能在缩放时保留蒙版边缘细节,避免模糊;
  3. 移除无效裁剪:原代码中对蒙版的cropped(to: ciImage.extent)操作无意义,因为蒙版尺寸小于原图,裁剪后依然无法对齐,替换为缩放后即可解决错位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:34:52