CIFilter/CIKernel中的最大图像尺寸? [英] maximum image size in CIFilter / CIKernel?

查看:79
本文介绍了CIFilter/CIKernel中的最大图像尺寸?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道使用自定义CIFilter对图像大小的限制吗?我创建了一个过滤器,当图像最大为2兆像素时,它会按预期执行,但是当图像较大时,会产生非常奇怪的结果.我已经在我的可可应用程序以及石英作曲家中对此进行了测试.我开发的滤镜是一种几何类型的失真滤镜(我认为),它需要ROI和跨越整个输入图像的DOD.我创建了用于重新映射全景图像的过滤器,因此我希望它可以用于非常大的图像(50-100兆像素).

Does anyone know what the limitations are on image size with custom CIFilters? I've created a filter that performs as expected when the images are up to 2 mega pixels but then produce very strange results when the images are larger. I've tested this both in my cocoa app as well as in quartz composer. The filter I've developed is a geometry-type distortion filter that (I think) requires an ROI and a DOD that spans the entire input image. I've created this filter for remapping panoramic images so I'd like this to work on very large (50-100 mega pixel) images.

作为一个简单的测试,请考虑下面的CIFilter(可以在Quartz Composer中使用),该CIFilter可以简单地转换图像,以便将图像的左下角转换为中心(我知道可以通过仿射来完成此操作)转换,但我需要在更复杂的过滤器中执行此类操作).当图像为2000x1000时,此滤镜可按预期工作,但当输入图像为4000x2000像素时,则产生奇怪的结果.问题是平移无法将角准确地移动到中心,或者图像输出完全消失了.我注意到大型图像上使用更复杂的滤镜还存在其他奇怪的问题,但是我认为这个简单的滤镜说明了我的问题,可以在Quartz Composer中进行复制.

As a simple test the consider the following CIFilter (can be used in Quartz Composer) that simply translates the image so that the lower-left corner of the images is translated to the center (I know this could be done with an affine transform but I need to perform such an operation in a more complex filter). This filter works as expected when the image is 2000x1000 but produces odd results when the input image is 4000x2000 pixels. The problem is that either the translation does not move the corner to the center exactly or that the image output is gone entirely. I've noticed other odd problems with more complicated filters on large images but I think this simple filter illustrates my issue and can be replicated in Quartz Composer.

kernel vec4 equidistantProjection(sampler src, __color color)
{
     vec2 coordinate = samplerCoord(src);
     vec2 result;
     vec4 outputImage;

     result.x = (coordinate.x - samplerSize(src).x / 2.0);
     result.y = (coordinate.y - samplerSize(src).y / 2.0);

     outputImage = unpremultiply(sample(src,result));

     return premultiply(outputImage);
}

使用工作坐标而不是采样器坐标时,会出现相同的奇怪行为,但是在这种情况下,对于尺寸为2000x1000的图像会发生错误,但对于尺寸为1000x500的图像会很好地工作

The same odd behavior appears when using the working coordinates instead of the sampler coordinates but in this case the error occurs for images of size 2000x1000 but works fine for images of size 1000x500

kernel vec4 equidistantProjection(sampler src, __color color, vec2 destinationDimensions)
{
     vec2 coordinate = destCoord();
     vec2 result;
     vec4 outputImage;

     result.x = (coordinate.x - destinationDimensions.x / 2.0);
     result.y = (coordinate.y - destinationDimensions.y / 2.0);

     outputImage = unpremultiply(sample(src,result));
     outputImage = unpremultiply(sample(src,samplerTransform(src, result)));

     return premultiply(outputImage);
}

作为参考,我在过滤器的-(CIImage *)outputImage 方法的Objective-C部分中添加了以下内容,以将DOD设置为整个输入图像.

For reference I have added to the Objective-C portion of my filter's - (CIImage *)outputImage method the following to set the DOD to be the entire input image.

- (CIImage *)outputImage
{
    CISampler *src = [CISampler samplerWithImage: inputImage];



     NSArray * outputExtent = [NSArray arrayWithObjects:
            [NSNumber numberWithInt:0],
            [NSNumber numberWithInt:0],
            [NSNumber numberWithFloat:[inputImage extent].size.width],
            [NSNumber numberWithFloat:[inputImage extent].size.height],nil];


return [self apply: filterKernel, src, inputColor, zoom, viewBounds, inputOrigin,
     kCIApplyOptionDefinition, [src definition], kCIApplyOptionExtent, outputExtent, nil];

}

另外,我添加了以下方法来设置我在-(id)init 方法中调用的ROI: [filterKernel setROISelector:@selector(regionOf:destRect:userInfo:)];

Additionally I added the following method to set the ROI which I call in my - (id)init method with this: [filterKernel setROISelector:@selector(regionOf:destRect:userInfo:)];

- (CGRect) regionOf:(int)samplerIndex destRect:(CGRect)r userInfo:obj
{

     return r;
}

在此问题上的任何帮助或建议,将不胜感激.我确信CIFilters可以处理较大的图像,因为我将CIBumpDistortion用于大于50兆像素的图像,所以我一定做错了.有什么想法吗?

Any help or advice on this issue would be greatly appreciated. I'm sure that CIFilters can work with larger images as I've used the CIBumpDistortion with greater than 50 megapixel images so I must be doing something wrong. Any ideas?

推荐答案

使用CoreImage,我发现它可以将大图像切成一部分.例如,在您的情况下,可以将4k x 2k图像拆分为4 2k x 1k图像并分别进行渲染.不幸的是,这种优化技巧会影响 samplerCoord ,并且某些依赖于坐标的滤镜无法在大图像上正常工作.

Working with the CoreImage I discovered that it cuts big images to parts. For example, in your case 4k x 2k image can be splitted to 4 2k x 1k images and rendered separately. Unfortunately, this optimization tricks affects samplerCoord and some coordinate-depended filters work incorrectly on big images.

我的解决方案是使用 destCoord 而不是 samplerCoord .当然,您应该记住,图像可以以非零原点和 destCoord 进行渲染.我编写了自己的过滤器,因此能够将整个范围作为vec4参数传递.

My solution was in using destCoord instead of samplerCoord. Of course, you should keep in mind that an image can be rendered in non-zero origin and destCoord. I wrote my own filter, so I was able to pass whole extent as a vec4 parameter.

示例:尝试使用CIFilter生成图像,如下所示:

Example: try generate an image with CIFilter, something like that:

float gray = (samplerCoord.x / samplerSize.width) * (samplerCoord.y / samplerSize.height);

此输出应使我们在(0,0)处为黑色,在(1,1)处为白色,对吗?但是,对于大图像,您会看到很少的四边形,而不是单个渐变.发生这种情况是由于CoreImage引擎优化了渲染,我还没有找到传递它的方法,但是您可以通过以下方式重新编写内核:

This output should give us black color at (0,0) and white at (1,1), right? However, for big images you'll see few quads, not a single gradient. This happens due to optimized rendering coming from CoreImage engine, I haven't found a way to pass it, but you can re-write the kernel this way:

float gray = ((destCoord.x - rect.x) / rect.size) * ((destCoord.y - rect.y) / rect.height)

rect 是必须通过的采样器的真实范围.我为此目的使用了[inputImage范围],但它取决于过滤器,在您的情况下可以是其他类型.

Where rect is real extent of the sampler you must pass. I used [inputImage extent] for this purpose, but it depends on filter and can be something other in your case.

希望这个解释很清楚.顺便说一句,看起来系统内核即使在大图像下也可以正常工作,因此您应该只担心自定义内核中的这些技巧.

Hope this explanation made it clear. Buy the way, it looks like system kernels work just fine even with big images, so you should worry about this tricks in your custom kernels only.

这篇关于CIFilter/CIKernel中的最大图像尺寸?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆