I'm trying to know how similar two images are. For that, I'm using VNGenerateImageFeaturePrintRequest and generating a VNFeaturePrintObservation from an image. Then for the two different images, I'm computing feature distance by using their VNFeaturePrintObservation. Unfortunately, computed distances are different for iOS 16.0 and iOS 17.0 thus failing my threshold value.

I tried to get featurePrintObservation for images like below,

let requestHandler = VNImageRequestHandler(cgImage: cgImage, options: [:])       
    let request = VNGenerateImageFeaturePrintRequest()
       do {               
          try requestHandler.perform([request])              
          self.feature = request.results?.first
        } catch {
            print("Vision error: \(error)")
       }

Then I tried to compute distance between two feature like below,

try! feature1.computeDistance(&visionDistance, to: feature2)

The output result "visionDistance" is different for iOS 16.0 and iOS 17.0 for the same two images (For example, '22.66224' in iOS 16.3.1 and '1.2178229' in iOS 17.0.1). I want to know if VNFeaturePrintObservation has changed in iOS 17.0 or not, and if changed then is there any way to generalize the calculation for both of the iPhone operating systems?

1

There are 1 best solutions below

1
evergreen_herb On

A colleage and I wrote a detailed article about VNGenerateImageFeaturePrintRequest and the differences between iOS16 and iOS17 (you can find it on Medium).

To sum up the differences:

  • On iOS16, a VNFeaturePrintObservation is a non-normalized vector containing 2048 Float.
  • On iOS17, it's a normalized vector having length 768.

Also, the computeDistance(_:to:) method computes the straightforward euclidian distance between those vectors.

As a consequence:

  • On iOS17, the distance between two observations is always less than 2.0.
  • On iOS16, the distance can vary a lot; typical values range between 0.0 and 40.0.

So, yes, this change can be quite annoying. Note that you can reproduce the iOS16 behavior on iOS17 by setting the revision property of a VNGenerateImageFeaturePrintRequest instance to VNGenerateImageFeaturePrintRequestRevision1 (distance values will not be exactly the same though, you'll get slight, non-significant differences).

If you have to support only iOS17, I would recommend to prefer the iOS17 VNGenerateImageFeaturePrintRequestRevision2 algorithm, since comparing normalized vectors makes much more sense (the distance between normalized vectors is closely related to their cosine distance, a popular measure of vector similarity in data analysis).