Abe*_*Abe 5 iphone computer-vision camera-calibration ios swift
我们如何使用苹果提供的函数(如下)进行直线转换?
Apple 在 'AVCameraCalibrationData.h' 中提供了关于如何校正图像的镜头失真的参考实现。即从使用广角或长焦镜头拍摄的图像到直线“真实世界”图像。图示如下:
要创建一个直线图像,我们必须从一个空的目标缓冲区开始,逐行遍历它,为输出图像中的每个点调用下面的示例实现,传递 lensDistortionLookupTable 以找到失真图像中的相应值,并将其写入到您的输出缓冲区。
func lensDistortionPoint(for point: CGPoint, lookupTable: Data, distortionOpticalCenter opticalCenter: CGPoint, imageSize: CGSize) -> CGPoint {
// The lookup table holds the relative radial magnification for n linearly spaced radii.
// The first position corresponds to radius = 0
// The last position corresponds to the largest radius found in the image.
// Determine the maximum radius.
let delta_ocx_max = Float(max(opticalCenter.x, imageSize.width - opticalCenter.x))
let delta_ocy_max = Float(max(opticalCenter.y, imageSize.height - opticalCenter.y))
let r_max = sqrt(delta_ocx_max * delta_ocx_max + delta_ocy_max * delta_ocy_max)
// Determine the vector from the optical center to the given point.
let v_point_x = Float(point.x - opticalCenter.x)
let v_point_y = Float(point.y - opticalCenter.y)
// Determine the radius of the given point.
let r_point = sqrt(v_point_x * v_point_x + v_point_y * v_point_y)
// Look up the relative radial magnification to apply in the provided lookup table
let magnification: Float = lookupTable.withUnsafeBytes { (lookupTableValues: UnsafePointer<Float>) in
let lookupTableCount = lookupTable.count / MemoryLayout<Float>.size
if r_point < r_max {
// Linear interpolation
let val = r_point * Float(lookupTableCount - 1) / r_max
let idx = Int(val)
let frac = val - Float(idx)
let mag_1 = lookupTableValues[idx]
let mag_2 = lookupTableValues[idx + 1]
return (1.0 - frac) * mag_1 + frac * mag_2
} else {
return lookupTableValues[lookupTableCount - 1]
}
}
// Apply radial magnification
let new_v_point_x = v_point_x + magnification * v_point_x
let new_v_point_y = v_point_y + magnification * v_point_y
// Construct output
return CGPoint(x: opticalCenter.x + CGFloat(new_v_point_x), y: opticalCenter.y + CGFloat(new_v_point_y))
}
Run Code Online (Sandbox Code Playgroud)
另外苹果声明:下面的“point”、“opticalCenter”和“imageSize”参数必须在同一坐标系中。
考虑到这一点,我们通过什么值opticalCenter和imageSize为什么?“应用径向放大”究竟是做什么的?
在opticalCenter实际命名distortionOpticalCenter。所以你可以lensDistortionCenter从 AVCameraCalibrationData提供。
图像大小是要直线化的图像的高度和宽度。
“应用径向放大”。它将给定点的坐标更改为使用理想镜头而不会失真的点。
“我们如何使用该功能......”。我们应该创建一个与扭曲图像大小相同的空缓冲区。对于空缓冲区的每个像素,我们应该应用 lensDistortionPointForPoint 函数。并将具有校正坐标的像素从扭曲的图像带到空缓冲区。填充所有缓冲区空间后,您应该得到一个未失真的图像。
| 归档时间: |
|
| 查看次数: |
725 次 |
| 最近记录: |