通用技术 python3 下比较图片相似度

匿名 · 2018年09月28日 · 2829 次阅读
#!/usr/bing/env python
# -*- coding: utf-8 -*-
# @author: xxx
# @date  : 2018/9/27
# coding : utf-8

from PIL import Image

class CompareImage():

    def calculate(self, image1, image2):
        g = image1.histogram()
        s = image2.histogram()
        assert len(g) == len(s), "error"

        data = []

        for index in range(0, len(g)):
            if g[index] != s[index]:
                data.append(1 - abs(g[index] - s[index]) / max(g[index], s[index]))
            else:
                data.append(1)

        return sum(data) / len(g)


    def split_image(self, image, part_size):
        pw, ph = part_size
        w, h = image.size

        sub_image_list = []

        assert w % pw == h % ph == 0, "error"

        for i in range(0, w, pw):
            for j in range(0, h, ph):
                sub_image = image.crop((i, j, i + pw, j + ph)).copy()
                sub_image_list.append(sub_image)

        return sub_image_list


    def compare_image(self, file_image1, file_image2, size=(256, 256), part_size=(64, 64)):
        '''
        'file_image1'和'file_image2'是传入的文件路径
         可以通过'Image.open(path)'创建'image1' 和 'image2' Image 对象.
         'size' 重新将 image 对象的尺寸进行重置,默认大小为256 * 256 .
         'part_size' 定义了分割图片的大小.默认大小为64*64 .
         返回值是 'image1' 和 'image2'对比后的相似度,相似度越高,图片越接近,达到1.0说明图片完全相同。
        '''

        image1 = Image.open(file_image1)
        image2 = Image.open(file_image2)

        img1 = image1.resize(size).convert("RGB")
        sub_image1 = self.split_image(img1, part_size)

        img2 = image2.resize(size).convert("RGB")
        sub_image2 = self.split_image(img2, part_size)

        sub_data = 0
        for im1, im2 in zip(sub_image1, sub_image2):
            sub_data += self.calculate(im1, im2)

        x = size[0] / part_size[0]
        y = size[1] / part_size[1]

        pre = round((sub_data / (x * y)), 6)
        # print(str(pre * 100) + '%')
        print('Compare the image result is: ' + str(pre))
        return pre

compare_image = CompareImage()
compare_image.compare_image("1.jpg", "2.jpg")

识别的图片:

运行结果:
Compare the image result is: 0.379042

参考:https://www.cnblogs.com/wozijisun/p/6478388.html
原作者 github:https://github.com/MashiMaroLjc/Learn-to-identify-similar-images

共收到 4 条回复 时间 点赞

openCV 了解一下

from skimage.measure import compare_ssim
import cv2

imageA = cv2.imread('/home/python/img_1.jpg')
imageB = cv2.imread('/home/python/img_2.jpg')

grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)

(score, diff) = compare_ssim(grayA, grayB, full=True)
print("SSIM: {}".format(score))

输出:SSIM: 0.3489060114239266

确实看不懂这是何种算法,单摆浮搁全明白,放一起不知道啥意思 。因为最近心烦意乱;
在阮一峰的 blog 上我找到了这个http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html

另外仅仅是凭靠直觉

data.append(1 - abs(g[index] - s[index]) / max(g[index], s[index]))

这个 max 是否是个奇怪的东西,有了 im1,im2,感觉分母就确定了,为啥还要取最大;

以上纯属胡说,不喜可喷;

另外 shebang 那行拼错了

匿名 #4 · 2018年11月13日
果冻 回复

试过 openCV,但是效率貌似是这个的三分之一,所以选了这个。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册