如何检查具有不同像素化的两张图像的相似性

Posted

技术标签:

【中文标题】如何检查具有不同像素化的两张图像的相似性【英文标题】:How to check similarity of two images that have different pixelization 【发布时间】:2019-03-15 02:59:53 【问题描述】:

我正在运行一个 python 代码来检查 Quora 和 Twitter 用户个人资料照片的相似性,但是当图像相同时我没有得到肯定的结果。

这是比较两张图片的代码:

path_photo_quora= "/home/yousuf/Desktop/quora_photo.jpg"
path_photo_twitter="/home/yousuf/Desktop/twitter_photo.jpeg"
if open(path_photo_quora,"rb").read() == open(path_photo_twitter,"rb").read():
     print('photos profile are identical')

尽管图像相同,但控制台未打印“照片配置文件相同”,我该怎么办?

【问题讨论】:

Checking images for similarity with OpenCV的可能重复 【参考方案1】:

您可以使用imagehash 库来比较相似的图像。

from PIL import Image
import imagehash
hash0 = imagehash.average_hash(Image.open('quora_photo.jpg')) 
hash1 = imagehash.average_hash(Image.open('twitter_photo.jpeg')) 
cutoff = 5  # maximum bits that could be different between the hashes. 

if hash0 - hash1 < cutoff:
  print('images are similar')
else:
  print('images are not similar')

由于图像不完全相同,会有一些差异,因此我们使用具有可接受的最大差异的截止值。哈希对象之间的差异是翻转的位数。但即使图像被调整大小、压缩、不同的文件格式或调整了对比度或颜色,imagehash 也能正常工作。

哈希(实际上是指纹)来自图像的 8x8 单色缩略图。但即使样本如此减少,相似性比较也会给出相当准确的结果。调整临界值以在误报和漏报之间找到可接受的平衡。

对于 64 位哈希,0 的差异意味着哈希是相同的。 32 的差异意味着根本没有相似之处。 64 的差异意味着一个哈希值是另一个哈希值的完全负数。

【讨论】:

有没有办法在不下载的情况下在线处理这些图像?即给出代码图像的 url 而不是本地路径? 不在库本身中。您必须使用 requests 之类的东西通过 http 下载图像。这只是几行代码。 ***.com/a/32859290/1977847 我不想在本地机器上下载图片,因为处理数百万张图片会占用太多空间 如果你使用我链接的代码,图像只会在内存中处理。除非您明确这样做,否则它们不会存储到您的驱动器中。 @MDP,是的。因为图像在散列之前被调整为相同的小尺寸。通常为 8x8 像素。【参考方案2】:

这两个图像不一样 - 只是成像的东西。正如您自己所注意到的,这些图像显然是不同的大小。因此,比较肯定会失败。

您需要使用某种相似性检查。第一步是将较小的图像放大到较大的图像。然后,您需要采用某种方法来检测和定义相似性。有不同的方法和方法,它们的任何组合都可能是有效的。

例如见Checking images for similarity with OpenCV

【讨论】:

【参考方案3】:
import cv2

class CompareImage(object):

    def __init__(self, image_1_path, image_2_path):
        self.minimum_commutative_image_diff = 1
        self.image_1_path = image_1_path
        self.image_2_path = image_2_path

    def compare_image(self):
        image_1 = cv2.imread(self.image_1_path, 0)
        image_2 = cv2.imread(self.image_2_path, 0)
        commutative_image_diff = self.get_image_difference(image_1, image_2)

        if commutative_image_diff < self.minimum_commutative_image_diff:
            print "Matched"
            return commutative_image_diff
        return 10000 //random failure value

    @staticmethod
    def get_image_difference(image_1, image_2):
        first_image_hist = cv2.calcHist([image_1], [0], None, [256], [0, 256])
        second_image_hist = cv2.calcHist([image_2], [0], None, [256], [0, 256])

        img_hist_diff = cv2.compareHist(first_image_hist, second_image_hist, cv2.HISTCMP_BHATTACHARYYA)
        img_template_probability_match = cv2.matchTemplate(first_image_hist, second_image_hist, cv2.TM_CCOEFF_NORMED)[0][0]
        img_template_diff = 1 - img_template_probability_match

        # taking only 10% of histogram diff, since it's less accurate than template method
        commutative_image_diff = (img_hist_diff / 10) + img_template_diff
        return commutative_image_diff


    if __name__ == '__main__':
        compare_image = CompareImage('image1/path', 'image2/path')
        image_difference = compare_image.compare_image()
        print image_difference

【讨论】:

以上是关于如何检查具有不同像素化的两张图像的相似性的主要内容,如果未能解决你的问题,请参考以下文章

图像的视觉内容完全相同,但像素值不同

C#怎么来判断2张图片相似度

iOS图像比较算法在两张非常相似但不同的照片中找到差异

如何对深度图像进行双边滤波器处理

python图像识别---------图片相似度计算

OpenCV比较两个图像并获得不同的像素