识别照片时的时间差Swift

Timing difference when recognizing photos Swift

我创建了一个识别照片中花朵的应用程序。照片可以来自画廊或用相机拍摄。我有功能:

func detectFlower(image: CIImage,completion: @escaping (_ getString:String?,_ error:Error?,_ getDouble:Double?,_ getArray:Array<VNConfidence>?,_ getArray:Array<String>?)-> Void)  {
        
        guard let model = try? VNCoreMLModel(for: NewFlowersModel().model) else {
            
            fatalError("Cannot import a model.")
        }
        let methodStart = Date()
        let request = VNCoreMLRequest(model: model) { (request, error) in
            
            let classifiedNameOfFlower = request.results?.first as? VNClassificationObservation
            let classifiedValues = request.results as? [VNClassificationObservation]
            let methodFinish = Date()
            let nameOfFlower = String(classifiedNameOfFlower?.identifier ?? "Unexpected type")
            let executionTime = methodFinish.timeIntervalSince(methodStart)
            
            let classificationConfidences = classifiedValues?.prefix(10).map {
                ([=11=].confidence)
            }
            
            let classificationIdentifiers = classifiedValues?.prefix(10).map {
                ([=11=].identifier)
            }
            completion(nameOfFlower,nil,executionTime, classificationConfidences, classificationIdentifiers)
        }
        
        let handler = VNImageRequestHandler(ciImage: image)
        do {
            try handler.perform([request])
        } catch {
            print(error)
            completion(nil, error, nil, nil, nil)
        }
    }

用于识别。其中有两个常量let methodStart = Date()let methodFinish = Date()用于测量时间。稍后在代码中有一个计算差异的常量 let executionTime = methodFinish.timeIntervalSince(methodStart).

我注意到一个奇怪的依赖 - 当我 运行 应用程序时,第一次扫描 returns 一个时间差,例如0.395959 秒。下一次扫描 returns 时间要短得多,例如 0.033615 秒。这可能是什么结果?是什么原因造成的时间差,第一次扫描,总是这个时间最长?

这段时间大部分时间可能是从磁盘加载模型。每次进行检测时,您都在重新创建整个模型:

guard let model = try? VNCoreMLModel(for: NewFlowersModel().model) else { ... }

第一次这样做时,您需要从磁盘加载大量数据。之后,其中大部分将被缓存,但这通常不是正确的方法,因为您仍然在重新创建数据结构上浪费大量精力。

您要做的是只创建一次模型和请求,可能是在应用程序启动期间,或者当您来到此屏幕时,或者在您认为用户需要 ML 引擎时。将其存储在 属性 或共享对象中。然后,每次获得新图像时,只需创建 VNImageRequestHandler 并执行它即可。