【问题标题】:CIGaussianBlur Quality: Banding & ArtifactsCIGaussianBlur 质量:条带和伪影
【发布时间】:2017-02-12 20:07:08
【问题描述】:

我正在尝试模糊 applicationWillResignActive 上的 AVCaptureVideoPreviewLayer,就像在股票 iOS Camera App 中一样。

由于光栅化 AVCaptureVideoPreviewLayer 和模糊本身会产生一个空帧,我通过从 didOutputSampleBufferapplicationWillResignActive 保留一个 CIImage 来接近它,我把 CIImage -> Apply CIFilter CIGaussianBlur 添加到它,添加一个 UIImageView 到 AVCaptureVideoPreviewLayer 并使 UIImageView 的 图像成为我应用 CIGaussianBlur 的模糊的 UIImage 版本。

到目前为止,这似乎工作正常......但是,它似乎产生了相当多的条带,显示高斯模糊的质量问题。

抓取框架:

func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!) {

            let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
            CVPixelBufferLockBaseAddress(imageBuffer!, CVPixelBufferLockFlags(rawValue: CVOptionFlags(0)))

            let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer!)

            let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer!)
            let width = CVPixelBufferGetWidth(imageBuffer!)
            let height = CVPixelBufferGetHeight(imageBuffer!)

            let colorSpace = CGColorSpaceCreateDeviceRGB()

            let bitmap = CGBitmapInfo(rawValue: CGBitmapInfo.ByteOrder32Little.rawValue|CGImageAlphaInfo.PremultipliedFirst.rawValue)
            let context = CGBitmapContextCreate(baseAddress, width, height, 8,
                                                bytesPerRow, colorSpace, bitmap.rawValue)
            let quartzImage = CGBitmapContextCreateImage(context!)
            CVPixelBufferUnlockBaseAddress(imageBuffer!,CVPixelBufferLockFlags(rawValue: CVOptionFlags(0)))

            self.cameraBufferImage = CIImage(CGImage: quartzImage!)
}

应用 CIGaussianBlur:

func blurPreviewWindow() {
    let previewLayer = self.previewView.layer as? AVCaptureVideoPreviewLayer
    previewLayer?.connection.enabled = false

    let context = CIContext(options: nil)
    let inputImage = self.cameraBufferImage!.imageByApplyingOrientation(6)

    let clampFilter = CIFilter(name: "CIAffineClamp")
    clampFilter!.setDefaults()
    clampFilter!.setValue(inputImage, forKey: "inputImage")

    if let currentFilter = CIFilter(name: "CIGaussianBlur") {
        currentFilter.setValue(clampFilter!.outputImage, forKey: "inputImage")
        currentFilter.setValue(50.0, forKey: "inputRadius")

        if let output = currentFilter.outputImage {
            if let cgimg = context.createCGImage(output, fromRect: inputImage.extent) {
                let processedImage = UIImage(CGImage: cgimg)
                self.previewBlurImageView = UIImageView(frame: self.previewView.bounds)
                self.previewBlurImageView?.alpha = 0
                self.previewView.addSubview(self.previewBlurImageView!)
                self.previewBlurImageView?.image = processedImage
                self.previewBlurImageView?.contentMode = .ScaleToFill
                self.previewBlurImageView?.layer.filters = [currentFilter]

                UIView.animateWithDuration(0.2, delay: 0.0, options: [.BeginFromCurrentState], animations: {
                                                () -> Void in
                    self.previewBlurImageView?.alpha = 1
                }, completion: { _ in })
            }
        }
    }
}

在这个 iOS 10 时代可能会有完全不同的方法吗?

更新:

这可能是色彩空间问题吗?由于测试设备是iPhone 7,颜色很广?

【问题讨论】:

  • 尝试使用与你不需要的模糊相关的不同 CIfilter("CIBoxBlur", "CIDiscBlur", "CiGaussianBlur", "CIMaskedVariableBlur" "CIMedianFilter","CIMotionBlur", "CIZoomBlur",)更改您的任何代码。只需更改 cifilter 名称。看看有什么不同....
  • 似乎其他过滤器也这样做,但有些过滤器比其他过滤器少。最重要的部分是,只有 CIGaussianBlur 提供了我正在寻找的外观。可能是我提取 CIImage 的方式?可能有完全不同的方法来模糊 AVCapturePreviewLayer?
  • 查看链接,您必须构建自己的 colorKernal 才能实现新的自定义过滤器。这是一个复杂的过程,但花一点时间就可以完成这项工作......
  • stackoverflow.com/questions/32378666/… 这解决了你的问题。我强烈建议您转到 flexmokey 并学习有关创建自定义过滤器的信息。独特的过滤器比本地过滤器更突出...永远记住...cu
  • 在应用过滤器之前尝试自动增强 inputImage

标签: ios swift avfoundation gaussian cifilter


【解决方案1】:

是 CIContext。

改变:

let context = CIContext(options: nil)

收件人:

let context = CIContext(options: [kCIContextWorkingColorSpace: CGColorSpaceCreateDeviceRGB(),
                                  kCIContextOutputColorSpace: CGColorSpaceCreateDeviceRGB(), 
                                  kCIContextUseSoftwareRenderer: false])

没有更多的条带或伪影!!!

【讨论】:

  • 我很高兴这对你有用,但它可能仍然比你需要做更多的工作。如果您只想要“UI 风格”的模糊效果,您是否尝试过将捕获预览层放在 UIVisualEffectView 中?
  • 我一直都有这个。与高斯模糊相比,UIVisualEffectView 有时看起来有点模糊。
  • 出于好奇,您知道最初的默认工作和输出色彩空间是什么吗?
  • 我没有。切换 kCIContextUseSoftwareRenderer 对模糊没有影响。
猜你喜欢
  • 1970-01-01
  • 2018-05-10
  • 1970-01-01
  • 2018-08-22
  • 2016-01-04
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多