Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 循环进化链导致整数溢出_Swift_Xcode_Image Processing_Convolution_Core Image - Fatal编程技术网

Swift 循环进化链导致整数溢出

Swift 循环进化链导致整数溢出,swift,xcode,image-processing,convolution,core-image,Swift,Xcode,Image Processing,Convolution,Core Image,我一直在使用Core Image的卷积滤波器进行一些工作,我注意到足够长的卷积链会导致意外的输出,我怀疑这是用于保存像素数据的基本整数、浮点或半浮点类型的数字溢出的结果。这尤其出乎意料,因为文档中说每个卷积的输出值都是,所以越大的值不应该在滤波器的连续过程中累积,但这似乎正是正在发生的事情 我这里有一些示例代码来演示这种令人惊讶的行为。您应该能够将它按原样粘贴到几乎任何Xcode项目中,在它的末尾设置一个断点,在适当的平台上运行它(我使用的是iPhone Xs,而不是模拟器),然后在出现中断时使

我一直在使用Core Image的卷积滤波器进行一些工作,我注意到足够长的卷积链会导致意外的输出,我怀疑这是用于保存像素数据的基本整数、浮点或半浮点类型的数字溢出的结果。这尤其出乎意料,因为文档中说每个卷积的输出值都是,所以越大的值不应该在滤波器的连续过程中累积,但这似乎正是正在发生的事情

我这里有一些示例代码来演示这种令人惊讶的行为。您应该能够将它按原样粘贴到几乎任何Xcode项目中,在它的末尾设置一个断点,在适当的平台上运行它(我使用的是iPhone Xs,而不是模拟器),然后在出现中断时使用快速查找来检查过滤器链

import CoreImage
import CoreImage.CIFilterBuiltins


// --------------------
// CREATE A WHITE IMAGE
// --------------------

// the desired size of the image
let size = CGSize(width: 300, height: 300)

// create a pixel buffer to use as input; every pixel is bgra(0,0,0,0) by default
var pixelBufferOut: CVPixelBuffer?
CVPixelBufferCreate(kCFAllocatorDefault, Int(size.width), Int(size.height), kCVPixelFormatType_32BGRA, nil, &pixelBufferOut)
let input = pixelBufferOut!

// create an image from the input
let image = CIImage(cvImageBuffer: input)

// create a color matrix filter that will turn every pixel white
// bgra(0,0,0,0) becomes bgra(1,1,1,1)
let matrixFilter = CIFilter.colorMatrix()
matrixFilter.biasVector = CIVector(string: "1 1 1 1")

// turn the image white
matrixFilter.inputImage = image
let whiteImage = matrixFilter.outputImage!

// the matrix filter sets the image's extent to infinity
// crop it back to original size so Quick Looks can display the image
let cropped = whiteImage.cropped(to: CGRect(origin: .zero, size: size))


// ------------------------------
// CONVOLVE THE IMAGE SEVEN TIMES
// ------------------------------

// create a 3x3 convolution filter with every weight set to 1
let convolutionFilter = CIFilter.convolution3X3()
convolutionFilter.weights = CIVector(string: "1 1 1 1 1 1 1 1 1")

// 1
convolutionFilter.inputImage = cropped
let convolved = convolutionFilter.outputImage!

// 2
convolutionFilter.inputImage = convolved
let convolvedx2 = convolutionFilter.outputImage!

// 3
convolutionFilter.inputImage = convolvedx2
let convolvedx3 = convolutionFilter.outputImage!

// 4
convolutionFilter.inputImage = convolvedx3
let convolvedx4 = convolutionFilter.outputImage!

// 5
convolutionFilter.inputImage = convolvedx4
let convolvedx5 = convolutionFilter.outputImage!

// 6
convolutionFilter.inputImage = convolvedx5
let convolvedx6 = convolutionFilter.outputImage!

// 7
convolutionFilter.inputImage = convolvedx6
let convolvedx7 = convolutionFilter.outputImage!

// <-- put a breakpoint here
// when you run the code you can hover over the variables
// to see what the image looks like at various stages through
// the filter chain; you will find that the image is still white
// up until the seventh convolution, at which point it turns black

导入CoreImage
导入CoreImage.CIFilterBuiltins
// --------------------
//创建白色图像
// --------------------
//图像的所需大小
let size=CGSize(宽:300,高:300)
//创建用作输入的像素缓冲区;默认情况下,每个像素都是bgra(0,0,0,0)
var pixelBufferOut:CVPixelBuffer?
CVPixelBufferCreate(kCFAllocatorDefault、Int(size.width)、Int(size.height)、KCVpixelFormattType_32BGRA、nil和pixelBufferOut)
让输入=像素缓冲输出!
//从输入创建图像
让image=CIImage(cvImageBuffer:输入)
//创建颜色矩阵过滤器,使每个像素变为白色
//bgra(0,0,0,0)变为bgra(1,1,1,1)
设matrixFilter=CIFilter.colorMatrix()
matrixFilter.biasVector=CIVector(字符串:“1”)
//将图像变成白色
matrixFilter.inputImage=图像
让whiteImage=matrixFilter.outputImage!
//矩阵过滤器将图像的范围设置为无穷大
//将其裁剪回原始大小,以便快速查看可以显示图像
let crapped=whiteImage.crapped(到:CGRect(原点:.0,大小:size))
// ------------------------------
//将图像卷积七次
// ------------------------------
//创建一个3x3卷积滤波器,每个权重设置为1
设卷积过滤器=CIFilter.卷积3x3()
卷积过滤器.weights=CIVector(字符串:“1”)
// 1
convolutionFilter.inputImage=裁剪
让convolved=convolutionFilter.outputImage!
// 2
convolutionFilter.inputImage=卷积
让convolvedx2=convolutionFilter.outputImage!
// 3
卷积过滤器.inputImage=卷积dx2
让convolvedx3=convolutionFilter.outputImage!
// 4
卷积过滤器.inputImage=卷积dx3
让convolvedx4=convolutionFilter.outputImage!
// 5
卷积过滤器.inputImage=convolvedx4
让convolvedx5=convolutionFilter.outputImage!
// 6
卷积过滤器.inputImage=卷积dx5
让convolvedx6=convolutionFilter.outputImage!
// 7
卷积过滤器.inputImage=卷积dx6
让convolvedx7=convolutionFilter.outputImage!

//文件似乎过时了。可能是因为在iOS上,内核映像默认使用8位无符号字节纹理格式,因为这些格式被限制在
0.0
1.0
之间

使用浮点型格式,值不再被钳制,而是存储为内核返回的值。由于您从白色(
1.0
)开始,并使用非标准化权重(
1
而不是
1/9
)应用了7个连续卷积,因此每个通道的值为9^7=4782969,超出了16位浮点范围

为了避免类似的情况,您应该规范化卷积权重,使其总和达到
1.0

顺便说一下:要创建特定大小的白色图像,只需执行以下操作:

let image = CIImage(color: .white).cropped(to: CGSize(width: 300, height: 300))

实际上,我一开始使用上述技术创建白色图像,但出乎意料的是,溢出没有发生,图像仍然是白色的。我的理论是,你必须用一个真正的像素缓冲区初始化你的CIImage,否则过滤器的执行只是在没有实际数据的情况下进行的。