通过自定义 CIFilter 运行图像时 CIImage 属性丢失
Posted
技术标签:
【中文标题】通过自定义 CIFilter 运行图像时 CIImage 属性丢失【英文标题】:CIImage properties are lost when running an image through a custom CIFilter 【发布时间】:2015-11-22 01:13:51 【问题描述】:当我使用预定义的 CIFilter 对象时,输入 CIImage 的属性会保留在输出 CIImage 中。
例如...
// 1. Gamma adjustment. After the following, gammaAdjusted image has the same properties as inputImage.
NSNumber * gammaExponent = [NSNumber numberWithFloat:0.2];
[_gammaAdjustFilter setValue:croppedImage forKey:@"inputImage"];
[_gammaAdjustFilter setValue:gammaExponent forKey:@"inputPower"];
CIImage * gammaAdjustedImage = _gammaAdjustFilter.outputImage;
然后我通过我的自定义 CIFilter 运行图像。
// 2. Difference of Gaussians.
_dogFilter.rad1 = 1.0;
_dogFilter.rad2 = 2.0;
_dogFilter.inputImage = gammaAdjustedImage;
CIImage * dogImage = _dogFilter.outputImage;
在此调用之后,dogImage.properties 为 NULL,并且在尝试访问它时甚至会崩溃。在调试下面自定义过滤器的实现时,blur1 是第一个返回的 CIImage,其中属性没有持久化到输出中。我最初认为可能是我应用内核的方式丢失了这些属性,而实际上它是 CIGaussianBlur 过滤器。
(lldb) po blur1.properties 错误:执行被中断,原因:EXC_BAD_ACCESS(代码=1,地址=0x0)。 进程已经返回到表达式求值前的状态。
-(CIImage *)outputImage
// Use the same input image both times.
[m_guassianBlurFilter setValue:self.inputImage forKey:@"inputImage"];
// Configure the first blurred image.
NSNumber * rad1Number = [NSNumber numberWithDouble:self.rad1];
[m_guassianBlurFilter setValue:rad1Number forKey:@"inputRadius"];
CIImage * blur1 = m_guassianBlurFilter.outputImage;
// Configure the second blurred image.
NSNumber * rad2Number = [NSNumber numberWithDouble:self.rad2];
[m_guassianBlurFilter setValue:rad2Number forKey:@"inputRadius"];
CIImage * blur2 = m_guassianBlurFilter.outputImage;
// Now diff them using the kernel.
CIKernelROICallback roi = ^CGRect (int index, CGRect destRect)
if ( CGRectIsInfinite(destRect) )
return CGRectNull;
else return destRect;
;
CIImage * DoG = [m_differenceKernel applyWithExtent:self.inputImage.extent roiCallback:roi arguments:@[blur1, blur2]];
return DoG;
【问题讨论】:
【参考方案1】:您可以尝试不同的方法来获得高斯差 (DoG)。它应该比建议的更快,并且运行完美。
- (CIImage *)makeDoG:(CIImage *)inputImage
CIFilter *gauss1 = [CIFilter filterWithName:@"CIGaussianBlur"];
[gauss1 setValue:inputImage forKey:@"inputImage"];
[gauss1 setValue:@(1) forKey:@"inputRadius"];
CIImage *tmpImage = gauss1.outputImage;
[gauss1 setValue:@(3.0) forKey:@"inputRadius"];
CIImage *tmpImage2 = gauss1.outputImage;
CIFilter *mixA = [CIFilter filterWithName:@"CISubtractBlendMode"];
[mixA setValue:tmpImage2 forKey:@"inputBackgroundImage"];
[mixA setValue:tmpImage forKey:@"inputImage"];
CIFilter *invert = [CIFilter filterWithName:@"CIColorInvert"];
[invert setValue:mixA.outputImage forKey:@"inputImage"];
return invert.outputImage;
【讨论】:
以上是关于通过自定义 CIFilter 运行图像时 CIImage 属性丢失的主要内容,如果未能解决你的问题,请参考以下文章
自定义 Metal CIFilter 中 RGB 通道的值范围是多少?