4

I've been trying to make an animal recognition app by image. My method is to compare the selected image by other images in an image array and list any comparisons that yield in a 90%+ similarity. Is there any other ways to compare two images that are similar, yet not alike? Any suggestions would be appreciated. These calculations must also run for many iterations, so a non-time consuming method would be much appreciated.

Please try to provide some code with the answer, as I am not very experienced in Swift.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Pannu
  • 96
  • 1
  • 12
  • 2
    http://stackoverflow.com/questions/11342897/how-to-compare-two-uiimage-objects – Arun Jan 04 '17 at 04:50
  • 1
    Use a third party library; don't attempt to build this yourself if you don't have a background in computer vision. (not apple's CIDetector, because its very limited). For instance: https://cloud.google.com/vision/ or https://www.microsoft.com/cognitive-services/en-us/computer-vision-api . – Josh Homann Jan 04 '17 at 04:53
  • 1
    Please check this answer may be it is useful for you [Compare images by certain percentages](http://stackoverflow.com/questions/6488732/how-does-one-compare-one-image-to-another-to-see-if-they-are-similar-by-a-certai) – Yogesh Mv Jan 04 '17 at 05:26
  • Possible duplicate of [How to compare two UIImage objects](http://stackoverflow.com/questions/11342897/how-to-compare-two-uiimage-objects) – Infinite Recursion Jan 19 '17 at 12:26

1 Answers1

3

you can do something like I did by analyzing one frame to the next and thresholding the difference (I didn't scale the image down yet, and probably should)

// called everytime a frame is captured
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {

    guard let imageBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer) else {
        return
    }

    CVPixelBufferLockBaseAddress(imageBufferRef, []);

    // set up for comparisons between prev and next images
    if prevPB == nil {
        prevPB = imageBufferRef
    }

    if (!isPlaying && motionIsDetected(prevPB, imageBufferRef) == 1) {
        isPlaying = true
        print("play video")
    }
    CVPixelBufferUnlockBaseAddress(imageBufferRef,[]);


    // if true, play the video
    prevPB = imageBufferRef
}


func pixelFrom(x: Int, y: Int, current: CVPixelBuffer) -> (UInt8, UInt8, UInt8) {
    let baseAddress = CVPixelBufferGetBaseAddress(current)
    let bytesPerRow = CVPixelBufferGetBytesPerRow(current)
    let buffer = baseAddress!.assumingMemoryBound(to: UInt8.self)
    let index = x*bytesPerRow+y

    let b = buffer[index]
    let g = buffer[index+1]
    let r = buffer[index+2]

    return (r, g, b)
}

func motionIsDetected(_ prev:CVPixelBuffer, _ current:CVPixelBuffer) -> Int {

    var differences = 0

    let baseAddress = CVPixelBufferGetBaseAddress(current)

    let width = CVPixelBufferGetWidth(current)
    let height = CVPixelBufferGetHeight(current)


    // THRESHOLDING: clamp by abs(aa-bb) for tuple of r,b,g  if 150 difference and at least 10 different pixels
    var MAGIC_THRESHOLD = 120
    var ENOUGH_DIFFERENCES = 10

    if (current != nil && prev != nil) {
        for x in 0..<height { //rows
            for y in 0..<width { //cols
                var setA = pixelFrom(x: x, y: y, current: prev)
                var setB = pixelFrom(x: x, y: y, current: current)
                if abs(Int(setA.0) - Int(setB.0)) > MAGIC_THRESHOLD && abs(Int(setA.1) - Int(setB.1)) > MAGIC_THRESHOLD && abs(Int(setA.2) - Int(setB.2)) > MAGIC_THRESHOLD {
                    differences = differences + 1
                }
            }
        }
    }
    print(" difference" )
    print(differences)

    if differences > ENOUGH_DIFFERENCES {
        return 1
    }
    return 0

}
user3325025
  • 654
  • 7
  • 10