swift-image icon indicating copy to clipboard operation
swift-image copied to clipboard

Is it posso lê to compare 2 images given a % diff threshold with this lib?

Open dennismozart1994 opened this issue 3 years ago • 1 comments

I saw a pretty cool video of wwdc regarding filtering our two images to generate a third one with the difference between the two compared ones... But it's not what I really need for the project I'm working on.

I need to compare two images given a % threshold of difference accepted between them... I would have an uiimage referenced with the expected result and compared with a runtime generated one... I found how to compare pixel by pixel out there, but I'd like to be more soft comparing in % so it does necessarily needs to match 100% the expected and actual results.

Is it possible to compare pixels/images with diff threshold with this lib? Would you have an example case on how to do that with two uiimage objects?

Thanks

Dennis

dennismozart1994 avatar Sep 23 '21 18:09 dennismozart1994

@dennismozart1994 There might be some simple answer to your question that I don't know of, and I'm certainly not qualified to speak on this subject, but I had an idea and I thought I'd share, just in case it helps you.

First of all, I don't know what kind of images you want to compare, and how would you prefer to calculate the difference (is green pixel more different from red than a blue pixel?). Given that, I'm just gonna assume that any pixel that doesn't have exactly the same color value as another pixel is considered 100% different.

With this in mind, you could go over each pixel of each image and count how many pixels are the same. Then divide the number of equal pixels by a number of total pixels, and as a result you get % of equal pixels.

It could look something like this (not tested):

func diff(imageA: NSImage, imageB: NSImage) -> Double {
    let pixelsA = Image<RGBA<UInt8>>(nsImage: imageA)
    let pixelsB = Image<RGBA<UInt8>>(nsImage: imageB)
    
    guard pixelsA.width == pixelsB.width && pixelsA.height == pixelsB.height else {
        fatalError("Images must be of the same size. Normalize first?")
    }
    
    var numEqualPixels = 0
    for x in 0..<pixelsA.width {
        for y in 0..<pixelsB.height {
            if pixelsA[x, y] == pixelsB[x, y] {
                numEqualPixels += 1
            }
        }
    }
    
    let totalPixels = pixelsA.width * pixelsA.height
    return Double(numEqualPixels) / Double(totalPixels)
}

This is the crucial line: if pixelsA[x, y] == pixelsB[x, y]. If this was a Image<RGBA<Bool>> image, this would definitely work. But if you have an image with color spectrum, then maybe you'd wanna do a little more elaborate comparison, and you could actually calculate more fine-grained difference between colors, rather than just "is same/is different".

timojaask avatar Nov 15 '21 23:11 timojaask