简体   繁体   English

在 CMSampleBuffer 中获取非矩形轮廓内 RGB 平均值的最快方法

[英]Fastest way to get the RGB average inside of a non-rectangular contour in the CMSampleBuffer

I am trying to get the RGB average inside of a non-rectangular multi-edge (closed) contour generated over a face landmark region in the frame (think of it as a face contour) from AVCaptureVideoDataOutput.我试图从 AVCaptureVideoDataOutput 获取在帧中的面部标志区域(将其视为面部轮廓)上生成的非矩形多边(闭合)轮廓内的 RGB 平均值。 I currently have the following code,我目前有以下代码,

        let landmarkPath = CGMutablePath()
        let landmarkPathPoints = landmark.normalizedPoints
            .map({ landmarkPoint in
                CGPoint(
                    x: landmarkPoint.y * faceBoundingBox.height + faceBoundingBox.origin.x,
                    y: landmarkPoint.x * faceBoundingBox.width + faceBoundingBox.origin.y)
            })
        landmarkPath.addLines(between: landmarkPathPoints)
        landmarkPath.closeSubpath()

        let averageFilter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: frame, kCIInputExtentKey: landmarkPath])!
        let outputImage = averageFilter.outputImage!

However, it currently throws *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType CGRectValue]: unrecognized selector sent to instance 0x283a57a80' terminating with uncaught exception of type NSException.但是,它当前抛出 *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFType CGRectValue]:无法识别的选择器发送到实例 0x283a57a80”以未捕获的 NSException 类型的异常终止。 I suspect this is as the kCIInputExtentKey is not a proper CIVector rectangular object.我怀疑这是因为 kCIInputExtentKey 不是正确的 CIVector 矩形 object。 Is there anyway to fix this?有没有什么办法解决这一问题? How can I define a non-rectangular region for the CIAreaAverage filter?如何为 CIAreaAverage 过滤器定义非矩形区域? If not possible, what's the most efficient way of getting the average RGB across the region of interest?如果不可能,在感兴趣的区域中获得平均 RGB 的最有效方法是什么?

Thanks a lot in advance!提前非常感谢!

If you could make all pixels outside of the contour transparent then you could use CIKmeans filter with inputCount equal 1 and the inputExtent set to the extent of the frame to get the average color of the area inside the contour (the output of the filter will contain 1-pixel image and the color of the pixel is what you are looking for).如果您可以使轮廓外的所有像素透明,那么您可以使用CIKmeans过滤器,其中inputCount等于1并将inputExtent设置为框架的范围以获得轮廓内区域的平均颜色(过滤器的 output 将包含1 像素图像和像素的颜色是您正在寻找的)。

Now, to make all pixels transparent outside of the contour, you could do something like this:现在,要使轮廓外的所有像素都透明,您可以执行以下操作:

  1. Create a mask image but setting all pixels inside the contour white and black outside (set background to black and fill the path with white).创建一个蒙版图像,但将轮廓内的所有像素设置为白色,外部设置为黑色(将背景设置为黑色并用白色填充路径)。
  2. Use CIBlendWithMask filter where:使用CIBlendWithMask过滤器,其中:
    • inputBackgroundImage is a fully transparent (clear) image inputBackgroundImage是完全透明(清晰)的图像
    • inputImage is the original frame inputImage是原始帧
    • inputMaskImage is the mask you created above inputMaskImage是您在上面创建的掩码

The output of that filter will give you the image with all pixels outside the contour fully transparent.该过滤器的 output 将为您提供轮廓外所有像素完全透明的图像。 And now you can use the CIKMeans filter with it as described at the beginning.现在您可以使用CIKMeans过滤器,如开头所述。

BTW, if you want to play with every single of the 230 filters out there check this app out: https://apps.apple.com/us/app/filter-magic/id1594986951顺便说一句,如果您想使用 230 个过滤器中的每一个,请查看此应用程序: https://apps.apple.com/us/app/filter-magic/id1594986951

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM