我正在将 ciimage 转换为单色,使用 CICrop 进行裁剪并运行 sobel 来检测边缘,底部的 #if 部分用于显示结果
CIImage *ci = [[CIImage alloc] initWithCGImage:uiImage.CGImage];
CIImage *gray = [CIFilter filterWithName:@"CIColorMonochrome" keysAndValues:
@"inputImage", ci, @"inputColor", [[CIColor alloc] initWithColor:[UIColor whiteColor]],
nil].outputImage;
CGRect rect = [ci extent];
rect.origin = CGPointZero;
CGRect cropRectLeft = CGRectMake(0, 0, rect.size.width * 0.2, rect.size.height);
CIVector *cropRect = [CIVector vectorWithX:rect.origin.x Y:rect.origin.y Z:rect.size.width* 0.2 W:rect.size.height];
CIImage *left = [gray imageByCroppingToRect:cropRectLeft];
CIFilter *cropFilter = [CIFilter filterWithName:@"CICrop"];
[cropFilter setValue:left forKey:@"inputImage"];
[cropFilter setValue:cropRect forKey:@"inputRectangle"];
// The sobel convoloution will produce an image that is 0.5,0.5,0.5,0.5 whereever the image is flat
// On edges the image will contain values that deviate from that based on the strength and
// direction of the edge
const double g = 1.;
const CGFloat weights[] = { 1*g, 0, -1*g,
2*g, 0, -2*g,
1*g, 0, -1*g};
left = [CIFilter filterWithName:@"CIConvolution3X3" keysAndValues:
@"inputImage", cropFilter.outputImage,
@"inputWeights", [CIVector vectorWithValues:weights count:9],
@"inputBias", @0.5,
nil].outputImage;
#define VISUALHELP 1
#if VISUALHELP
CGImageRef imageRefLeft = [gcicontext createCGImage:left fromRect:cropRectLeft];
CGContextDrawImage(context, cropRectLeft, imageRefLeft);
CGImageRelease(imageRefLeft);
#endif
现在,只要 3x3 卷积不是 ciimage 管道的一部分,我运行边缘检测的图像部分就会显示为灰色,但只要 CIConvolution3X3 后缀是处理管道的一部分,颜色就会神奇地出现。无论我使用 CIColorMonochrome 还是 CIPhotoEffectMono 前缀去除颜色,都会发生这种情况。任何想法如何将颜色一直保持到管道底部?tnx
UPD:毫不奇怪,运行一个粗略的自定义单色内核,比如这个
kernel vec4 gray(sampler image)
{
vec4 s = sample(image, samplerCoord(image));
float r = (s.r * .299 + s.g * .587 + s.b * 0.114) * s.a;
s = vec4(r, r, r, 1);
return s;
}
当 3x3 卷积是我的 ci 管道的一部分时,而不是使用来自苹果的标准单声道过滤器会导致颜色返回完全相同的问题