Compare similarity of images using OpenCV with Python

前端 未结 4 1779
走了就别回头了
走了就别回头了 2020-12-07 12:04

I\'m trying to compare a image to a list of other images and return a selection of images (like Google search images) of this list with up to 70% of similarity.

I ge

4条回答
  •  庸人自扰
    2020-12-07 12:11

    I wrote a program to do something very similar maybe 2 years ago using Python/Cython. Later I rewrote it to Go to get better performance. The base idea comes from findimagedupes IIRC.

    It basically computes a "fingerprint" for each image, and then compares these fingerprints to match similar images.

    The fingerprint is generated by resizing the image to 160x160, converting it to grayscale, adding some blur, normalizing it, then resizing it to 16x16 monochrome. At the end you have 256 bits of output: that's your fingerprint. This is very easy to do using convert:

    convert path[0] -sample 160x160! -modulate 100,0 -blur 3x99 \
        -normalize -equalize -sample 16x16 -threshold 50% -monochrome mono:-
    

    (The [0] in path[0] is used to only extract the first frame of animated GIFs; if you're not interested in such images you can just remove it.)

    After applying this to 2 images, you will have 2 (256-bit) fingerprints, fp1 and fp2.

    The similarity score of these 2 images is then computed by XORing these 2 values and counting the bits set to 1. To do this bit counting, you can use the bitsoncount() function from this answer:

    # fp1 and fp2 are stored as lists of 8 (32-bit) integers
    score = 0
    for n in range(8):
        score += bitsoncount(fp1[n] ^ fp2[n])
    

    score will be a number between 0 and 256 indicating how similar your images are. In my application I divide it by 2.56 (normalize to 0-100) and I've found that images with a normalized score of 20 or less are often identical.

    If you want to implement this method and use it to compare lots of images, I strongly suggest you use Cython (or just plain C) as much as possible: XORing and bit counting is very slow with pure Python integers.

    I'm really sorry but I can't find my Python code anymore. Right now I only have a Go version, but I'm afraid I can't post it here (tightly integrated in some other code, and probably a little ugly as it was my first serious program in Go...).

    There's also a very good "find by similarity" function in GQView/Geeqie; its source is here.

提交回复
热议问题