我正在编写一个简单的(至少我认为这很简单)自定义内核,它可以获取指定像素和整个图像的差异。 下面是我的代码,这只是制作过滤器。在操场上玩耍很不错。
import UIKit
import CoreImage
let Flower = CIImage( image: UIImage(named: "flower.png")!)!
class Test: CIFilter
{
var inputImage1 : CIImage?
var inputImage2 : CIImage?
var kernel = CIKernel(string:
"kernel vec4 colorRemap(sampler inputIm, sampler GaussIm) " +
"{ " +
"vec4 size = samplerExtent(inputIm); " +
"float row = 1.0; " +
"float column = 1.0; " +
"float pixelx = (column - 1.0)/(size.w - 1.0)+1.0/(2.0*size.z);" +
"float pixely = (size.z - row)/(size.z - 1.0)-1.0/(2.0*size.w);" +
"vec3 g0 =sample(GaussIm,vec2(pixelx,pixely)).rgb; " +
"vec3 current = sample(inputIm,samplerCoord(inputIm)).rgb; " +
"vec3 diff =(current - g0); " +
"return vec4(diff,1.0); " +
"} "
)
var extentFunction: (CGRect, CGRect) -> CGRect =
{ (a: CGRect, b: CGRect) in return CGRectZero }
override var outputImage: CIImage!
{
if let inputImage1 = inputImage1,
inputImage2 = inputImage2,
kernel = kernel
{
let extent = inputImage1.extent
let arguments = [inputImage1,inputImage2]
return kernel.applyWithExtent(extent,
roiCallback:
{ (index, rect) in
return rect
},
arguments: arguments)
}
return nil
}
}
要使用过滤器,您可以执行以下操作
let filter = Test()
filter.inputImage1 = Flower
filter.inputImage2 = Flower
let output = filter.outputImage
现在,在上面的代码中,我已经指出我们正在考虑位于GaussIm(1,1)处的像素之间的差异,就像我们将图像视为矩阵一样(在通常意义上的)和inputIm的整个图像。
在玩完之后,我开始意识到自定义内核语言对待图像有点像OpenGL。左下角映射到(0,0),右上角是(1,1),因此像素坐标是0到1之间的数字。问题是我想指定我想要的任何像素用来消除差异。
内核代码的前5行试图通过计算图像中每个像素位置的中心来缓解这种情况。考虑到OpenGL如何处理它的图像,或者可能有更好的方法,我不确定这是否正确。
为什么我得到的输出与MATLAB不同?它几乎看起来比我从自定义过滤器获得的颜色更暗,但它们同时接近相同的输出。我的想法是,它必须是定制内核在像素之间取得差异的方式,但我不确定发生了什么。
答案 0 :(得分:0)
我最终搞清楚了 - 裁剪的原因是由于图像的计算方式。这项工作是在操场上完成的,而不是在上下文中完成的,因此显示的任何内容都被剪切到[0,1]的范围内。修复此问题的方法是确保您正在进行计算的CIContext通过选项在计算中支持浮点精度。