Coder Social home page Coder Social logo

Comments (4)

danshev avatar danshev commented on June 28, 2024

Follow-up

Upon looking at the data types, I saw that OSHashType (this library's data type for the hash) is a signed, 64-bit integer. So, I'm converting the hexadecimal value (calculated by ImageHash) into a OSHashType directly.

Unfortunately, the resulting "distance" implies the two images (exact same) are very dissimilar.

Here is my code (and outputs) -- any thoughts?

// Calculate this library's pHash for a picture of me
let danImage = UIImage(named: "dan")
let danHash = myHasher.hashImage(danImage!, with: .pHash)
print(danHash)
>> -4467566139072037888

// Convert the Python, ImageHash pHash value (from the picture of me) into OSHashType
let unsignedVal = UInt64("bfbcf072a26094c3", radix: 16)!
let pythonHash = OSHashType(Int64(bitPattern: unsignedVal))
print(pythonHash)
>> -4630561941702535997

// Calculate this library's pHash for a picture of Britney Spears
let britImage = UIImage(named: "brit")
let britHash = myHasher.hashImage(britImage!, with: .pHash)
print(britHash)
>> 7825699685688937472


print(myHasher.hashDistance(danHash, to: britHash))
>> 26

// Calculate the distance between the Python pHash value of a picture of me
//       and this library's pHash value of a picture of me
print(myHasher.hashDistance(pythonHash, to: danHash))
>> 35 ... so the same pic of me is more different than a picture of me and Britney Spears...?

from cocoaimagehashing.

danshev avatar danshev commented on June 28, 2024

I'll close out this issue:

There are a number of differences between this library and the Python, ImageHash library which make the pHash values incompatible; examples (not exhaustive):

  1. The functions to resize the input images down to 32x32 pixel images are different; as a result, the RGB tuples are demonstrably different, which then cascades down to the grayscale calculations, the DCT calculations, etc., etc.

  2. The grayscale calculation is different:

  • This library uses a simple (R + B + G) / 3 calculation
  • Python ImageHash, which uses PIL / Pillow's convert() function, uses the ITU-R 601-2 luma transform (source)

from cocoaimagehashing.

ameingast avatar ameingast commented on June 28, 2024

Just some feedback from my side:

  • The library relies heavily on Apple libraries (UIKit, AppKit) for resizing, shrinking etc.
  • Greyscale computation could be changed to something else which makes it "more compatible" with the official standard. I don't want to break existing code, so this means extending the library.

Thanks for the feedback!

from cocoaimagehashing.

danshev avatar danshev commented on June 28, 2024

I was able to bring the this library's resizing better in-line with the ImageHash library by learning that the ImageHash library (along with most Python projects doing image manipulation) uses Pillow, which uses a Lanczos Scale transform as the default for its resize function.

brit-32-PIL
Pillow 32x32 resize

brit-32-pre
Original CocoaImageHashing resize

brit-32-post
Converted CocoaImageHashing resize

Note: to best-appreciate the difference, it's best to download the three images and scroll through them in a file browser (... you'll be able to use the thumbnail preview to see how they change):

ezgif com-video-to-gif-2

I replaced the RGBABitmapDataForResizedImageWithWidth() code with:

{
    UIImage *baseImage = [UIImage imageWithData:self];
    if (!baseImage) {
        return nil;
    }
    
    // Calculate the necessary InputScaleKey and InputAspectRatioKey values to resize to 32x32
    CGFloat scaleFactor = 32.0 / baseImage.size.height;
    CGFloat aspectRatio = baseImage.size.height / baseImage.size.width;
    
    CIImage *input_ciimage = [[CIImage alloc] initWithImage:baseImage];
    CIImage *output_ciimage = [
                               [CIFilter filterWithName:@"CILanczosScaleTransform" keysAndValues:kCIInputImageKey, input_ciimage, kCIInputScaleKey, [NSNumber numberWithFloat:scaleFactor], kCIInputAspectRatioKey, [NSNumber numberWithFloat:aspectRatio], nil] outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef output_cgimage = [context createCGImage:output_ciimage fromRect:[output_ciimage extent]];
    CFDataRef pixels = CGDataProviderCopyData(CGImageGetDataProvider(output_cgimage));
    
    NSData *finalData = (__bridge NSData *)pixels;
    
    CGImageRelease(output_cgimage);
    CFRelease(pixels);
    return finalData;
}

I changed the grayscale calculation, which was easy enough.

Unfortunately, I haven't been able to unwind how you've implemented the DCT, which is definitely producing a different result than the SciPy (default: Type II) implementation

Intersetingly enough, however, I also found some fairly glaring mistakes with the ImageHash implementation -- most notably using median (vs average) in the pixel comparison.

from cocoaimagehashing.

Related Issues (12)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.