是否可以使用从 iOS 11.3.1 上的图像以编程方式创建的 ARReferenceImage 对象
Is it possible to use ARReferenceImage objects created programatically from the images on iOS 11.3.1
我最近用原生的 ARKit 替换了笨重的 OpenCV 来进行图像检测和跟踪。我要跟踪的图像从 Web 服务下载并存储在本地。我正在使用以下代码从它们创建 ARImageReference
对象:
guard
let image = UIImage(contentsOfFile: imageLocalPath),
let cgImage = image.cgImage
else {
return nil
}
return ARReferenceImage(cgImage, orientation: .up, physicalWidth: 0.12)
宽度小,因为图片也没有那么大,每张大约180 x 240像素,但打印的可能更大。
根据当前 iOS 版本配置的会话,因为 ARImageTrackingConfiguration
不适用于 iOS 11:
private lazy var configuration: ARConfiguration = {
if #available(iOS 12.0, *),
ARImageTrackingConfiguration.isSupported {
return ARImageTrackingConfiguration()
}
return ARWorldTrackingConfiguration()
}()
if #available(iOS 12.0, *),
let imagesTrackingConfig = configuration as? ARImageTrackingConfiguration {
imagesTrackingConfig.trackingImages = referenceImages
} else if let worldTrackingConfig = configuration as? ARWorldTrackingConfiguration {
worldTrackingConfig.detectionImages = referenceImages
}
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
即使我使用 ARWorldTrackingConfiguration
,上面的代码也适用于 iOS 版本 12 和 13。 ARKit 正确检测到的图像。但是当我在 iOS 11.3.1 上尝试 运行 它时,应用程序立即崩溃并出现以下错误:
Assert:
/BuildRoot/Library/Caches/com.apple.xbs/Sources/AppleCV3D/AppleCV3D-1.13.11/library/VIO/OdometryEngine/src/FrameDownsampleNode/FrameDownsampler.cpp,
62: std::abs(static_cast(aspect_1) -
static_cast(src_frame.image.width * output_frame_height_)) <
max_slack (lldb)
12.0 以下的 iOS 版本是否无法以编程方式创建动态标记,或者我做错了什么?不幸的是,我无法找到有关特定版本的任何信息。任何反馈表示赞赏。谢谢。
所以过了一段时间,我终于找到了问题的根源,所以我把它贴在这里,因为它可能对遇到同样问题的其他人有用。
答案是 YES,可以通过编程方式创建 ARReferenceImage
对象,并在 iOS 11.3.1 上使用它们进行图像检测。
我的问题出在源图像本身,看起来 CGImage
的比例不当导致了崩溃。从 API 下载的图像为 180x240。通过检查用于创建 ARReferenceImage
的 CGImage
的大小,我意识到它们没有正确缩放,所以 CGImage
大小与源 [=16] 相同=].
我决定尝试使用以下方法重新绘制图像:
func getRedrawnCgImage(_ originalImage: UIImage) -> CGImage? {
guard let cgImage = originalImage.cgImage else { return nil }
let size = CGSize(width: cgImage.width, height: cgImage.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
originalImage.draw(in: CGRect(origin: .zero, size: size))
let redrawnImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return redrawnImage?.cgImage
}
结果 CGImage
的大小为 540x720,因此原始大小应为 x3。通过使用那些重新绘制的图像,我摆脱了崩溃,但这是一种解决方法,而不是目前的正确解决方案。
我最近用原生的 ARKit 替换了笨重的 OpenCV 来进行图像检测和跟踪。我要跟踪的图像从 Web 服务下载并存储在本地。我正在使用以下代码从它们创建 ARImageReference
对象:
guard
let image = UIImage(contentsOfFile: imageLocalPath),
let cgImage = image.cgImage
else {
return nil
}
return ARReferenceImage(cgImage, orientation: .up, physicalWidth: 0.12)
宽度小,因为图片也没有那么大,每张大约180 x 240像素,但打印的可能更大。
根据当前 iOS 版本配置的会话,因为 ARImageTrackingConfiguration
不适用于 iOS 11:
private lazy var configuration: ARConfiguration = {
if #available(iOS 12.0, *),
ARImageTrackingConfiguration.isSupported {
return ARImageTrackingConfiguration()
}
return ARWorldTrackingConfiguration()
}()
if #available(iOS 12.0, *),
let imagesTrackingConfig = configuration as? ARImageTrackingConfiguration {
imagesTrackingConfig.trackingImages = referenceImages
} else if let worldTrackingConfig = configuration as? ARWorldTrackingConfiguration {
worldTrackingConfig.detectionImages = referenceImages
}
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
即使我使用 ARWorldTrackingConfiguration
,上面的代码也适用于 iOS 版本 12 和 13。 ARKit 正确检测到的图像。但是当我在 iOS 11.3.1 上尝试 运行 它时,应用程序立即崩溃并出现以下错误:
Assert: /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppleCV3D/AppleCV3D-1.13.11/library/VIO/OdometryEngine/src/FrameDownsampleNode/FrameDownsampler.cpp, 62: std::abs(static_cast(aspect_1) - static_cast(src_frame.image.width * output_frame_height_)) < max_slack (lldb)
12.0 以下的 iOS 版本是否无法以编程方式创建动态标记,或者我做错了什么?不幸的是,我无法找到有关特定版本的任何信息。任何反馈表示赞赏。谢谢。
所以过了一段时间,我终于找到了问题的根源,所以我把它贴在这里,因为它可能对遇到同样问题的其他人有用。
答案是 YES,可以通过编程方式创建 ARReferenceImage
对象,并在 iOS 11.3.1 上使用它们进行图像检测。
我的问题出在源图像本身,看起来 CGImage
的比例不当导致了崩溃。从 API 下载的图像为 180x240。通过检查用于创建 ARReferenceImage
的 CGImage
的大小,我意识到它们没有正确缩放,所以 CGImage
大小与源 [=16] 相同=].
我决定尝试使用以下方法重新绘制图像:
func getRedrawnCgImage(_ originalImage: UIImage) -> CGImage? {
guard let cgImage = originalImage.cgImage else { return nil }
let size = CGSize(width: cgImage.width, height: cgImage.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
originalImage.draw(in: CGRect(origin: .zero, size: size))
let redrawnImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return redrawnImage?.cgImage
}
结果 CGImage
的大小为 540x720,因此原始大小应为 x3。通过使用那些重新绘制的图像,我摆脱了崩溃,但这是一种解决方法,而不是目前的正确解决方案。