iOS11 使用视觉框架VNDetectRectanglesRequest做物体检测不准确?
iOS 11 using vision framework VNDetectRectanglesRequest to do object detection not precisely?
Apple 在 iOS11 中有新功能,允许您使用视觉框架在没有模型的情况下进行对象检测。我尝试了这些新的 API,但发现 VNDetectRectanglesRequest 的结果不好。我是否正确使用了 API?
这里有一些很好的案例:
还有一些不好的案例:
这是我的代码:
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
// create the request
let request2 = VNDetectRectanglesRequest { (request, error) in
self.VNDetectRectanglesRequestCompletionBlock(request: request, error: error)
}
do {
request2.minimumConfidence = 0.7
try self.visionSequenceHandler.perform([request2], on: pixelBuffer)
} catch {
print("Throws: \(error)")
}
}
func VNDetectRectanglesRequestCompletionBlock(request: VNRequest, error: Error?) {
if let array = request.results {
if array.count > 0 {
let ob = array.first as? VNRectangleObservation
print("count: \(array.count)")
print("fps: \(self.measureFPS())")
DispatchQueue.main.async {
let boxRect = ob!.boundingBox
let transRect = self.transformRect(fromRect: boxRect, toViewRect: self.cameraLayer.frame)
var transformedRect = ob!.boundingBox
//transformedRect.origin.y = 1 - transformedRect.origin.y
let convertedRect = self.cameraLayer.layerRectConverted(fromMetadataOutputRect: transformedRect)
self.highlightView?.frame = convertedRect
}
}
}
}
你注释掉的行几乎是正确的,你需要把它放回去但把它改成:
transformedRect.origin.y = 1 - (transformedRect.origin.y + transformedRect.width)
你的'bad case'例子中的正方形实际上来自右边的毛绒玩具。
你的好人看起来不错,因为他们在屏幕中央。
已经提出了很多误解、期望和黑盒问题。但除此之外,您还错误地使用了 API。
矩形检测器会在图像中找到代表真实世界矩形的区域。在大多数情况下,捕捉图像的相机在透视中看到一个真实的矩形物体——因此它在 2D 图像平面上的 3D 投影通常不是矩形的。例如,您的一张照片中计算机屏幕的二维投影更呈梯形,因为顶角比底角离相机更远。
您可以通过查看检测到的矩形的实际角来获得此形状 — 查看 VNRectangleObservation 对象的属性。如果你在这四个角之间画线,你通常会发现一些东西可以更好地跟踪照片中电脑屏幕、一张纸等的形状。
boundingBox
属性 反而让你得到最小的矩形区域——也就是图像中的矩形 space——包含那些角点。所以它不会跟随真实矩形物体的形状,除非你的相机视角恰到好处。
Apple 在 iOS11 中有新功能,允许您使用视觉框架在没有模型的情况下进行对象检测。我尝试了这些新的 API,但发现 VNDetectRectanglesRequest 的结果不好。我是否正确使用了 API?
这里有一些很好的案例:
还有一些不好的案例:
这是我的代码:
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
// create the request
let request2 = VNDetectRectanglesRequest { (request, error) in
self.VNDetectRectanglesRequestCompletionBlock(request: request, error: error)
}
do {
request2.minimumConfidence = 0.7
try self.visionSequenceHandler.perform([request2], on: pixelBuffer)
} catch {
print("Throws: \(error)")
}
}
func VNDetectRectanglesRequestCompletionBlock(request: VNRequest, error: Error?) {
if let array = request.results {
if array.count > 0 {
let ob = array.first as? VNRectangleObservation
print("count: \(array.count)")
print("fps: \(self.measureFPS())")
DispatchQueue.main.async {
let boxRect = ob!.boundingBox
let transRect = self.transformRect(fromRect: boxRect, toViewRect: self.cameraLayer.frame)
var transformedRect = ob!.boundingBox
//transformedRect.origin.y = 1 - transformedRect.origin.y
let convertedRect = self.cameraLayer.layerRectConverted(fromMetadataOutputRect: transformedRect)
self.highlightView?.frame = convertedRect
}
}
}
}
你注释掉的行几乎是正确的,你需要把它放回去但把它改成:
transformedRect.origin.y = 1 - (transformedRect.origin.y + transformedRect.width)
你的'bad case'例子中的正方形实际上来自右边的毛绒玩具。 你的好人看起来不错,因为他们在屏幕中央。
已经提出了很多误解、期望和黑盒问题。但除此之外,您还错误地使用了 API。
矩形检测器会在图像中找到代表真实世界矩形的区域。在大多数情况下,捕捉图像的相机在透视中看到一个真实的矩形物体——因此它在 2D 图像平面上的 3D 投影通常不是矩形的。例如,您的一张照片中计算机屏幕的二维投影更呈梯形,因为顶角比底角离相机更远。
您可以通过查看检测到的矩形的实际角来获得此形状 — 查看 VNRectangleObservation 对象的属性。如果你在这四个角之间画线,你通常会发现一些东西可以更好地跟踪照片中电脑屏幕、一张纸等的形状。
boundingBox
属性 反而让你得到最小的矩形区域——也就是图像中的矩形 space——包含那些角点。所以它不会跟随真实矩形物体的形状,除非你的相机视角恰到好处。