使用Vision / CoreImage裁剪/合成图像

问题描述 投票:0回答:1

我正在使用iOS 13中的Vision框架,并正在尝试完成以下任务;

  • 拍摄图像(在这种情况下为CIImage,并使用Vision定位图像中的所有面部。
  • 将每张脸裁成自己的CIImage(我将其称为“脸部图像”)。
  • [使用CoreImage过滤器过滤每个面部图像,例如模糊或漫画效果。
  • 将面部图像重新组合到原始图像上,从而创建仅适用于面部的效果。

一个更好的例子是从AVCaptureSession处获取实时摄像机供稿并模糊视频帧中的每个面部,将模糊的面部重新组合回原始图像以进行保存的最终目标。

几乎可以正常工作,但似乎存在坐标/平移问题。例如,当我测试此代码并移动我的脸时,“模糊”部分的方向错误(如果我将脸右转,则该框将向左移动,如果我向上看,则该框将向下移动)。尽管我认为这可能与前置摄像头的镜像有关,但我似乎无法弄清楚下一步应该怎么做;

func drawFaceBox(bufferImage: CIImage, observations: [VNFaceObservation]) -> CVPixelBuffer? {

    // The filter
    let blur = CIFilter(name: "CICrystallize")

    // The unfiltered image, prepared for filtering
    var filteredImage = bufferImage

    // Find and crop each face
    if !observations.isEmpty {
        for face in observations {
            let faceRect = VNImageRectForNormalizedRect(face.boundingBox, Int(bufferImage.extent.size.width), Int(bufferImage.extent.size.height))
            let croppedFace = bufferImage.cropped(to: faceRect)
            blur?.setValue(croppedFace, forKey: kCIInputImageKey)
            blur?.setValue(10.0, forKey: kCIInputRadiusKey)
            if let blurred = blur?.value(forKey: kCIOutputImageKey) as? CIImage {
                compositorCIFilter?.setValue(blurred, forKey: kCIInputImageKey)
                compositorCIFilter?.setValue(filteredImage, forKey: kCIInputBackgroundImageKey)
                if let output = compositorCIFilter?.value(forKey: kCIOutputImageKey) as? CIImage {
                    filteredImage = output
                }
            }
        }
    }

    // Convert image to CVPixelBuffer and return.  This part works fine.

}

关于如何将模糊的人脸图像准确地恢复到其原始位置的任何想法?还是任何其他方法仅过滤原始CIImage的一部分,以完全避免/保存此问题?谢谢!

swift image-processing core-image apple-vision
1个回答
0
投票

我相信这个问题源于管道中较早的定向问题(特别是在从摄像机输出样本缓冲区的过程中,这是实例化Vision任务的地方)。我已经像这样更新了didOutputSampleBuffer代码;

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

        ...

        // Setup the current device orientation
        let curDeviceOrientation = UIDevice.current.orientation

        // Handle the image property orientation
        //let orientation = self.exifOrientation(from: curDeviceOrientation)

        // Setup the image request handler
        //let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, orientation: CGImagePropertyOrientation(rawValue: UInt32(1))!)
        let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:])

        // Setup the completion handler
        let completion: VNRequestCompletionHandler = {request, error in
            let observations = request.results as! [VNFaceObservation]

            // Draw faces
            DispatchQueue.main.async {

                // HANDLE FACES
                self.drawFaceBoxes(for: observations)

            }
        }

        // Setup the image request
        let request = VNDetectFaceRectanglesRequest(completionHandler: completion)

        // Handle the request
        do {
            try handler.perform([request])
        } catch {
            print(error)
        }
    }

[如上所述,我已经注释掉let orientation = ...和第一个let handler = ...,它们使用的是方向。通过删除对方向的引用,我似乎已经消除了Vision计算中与方向有关的任何问题。

© www.soinside.com 2019 - 2024. All rights reserved.