当前位置:   article > 正文

根据哈希值或者特征值判断图片是否相同

根据哈希值或者特征值判断图片是否相同

执行图像的批量判重工作时,您可以选用多种方法,具体取决于对"重复"的定义以及您关注的重复类型(是否允许缩放、旋转或轻微的变化)。
方式一:哈希比对
这种方法非常适合寻找几乎相同或者经过轻微缩放的重复图像。您可以使用像是平均哈希(aHash)、感知哈希(pHash)、差异哈希(dHash)等。
方法二:特征匹配
对于需要在图像中寻找相似部分或者某种程度的图像变化(如旋转、缩放)时,可以采用特征点提取和匹配方法,例如SIFT、SURF或ORB。然而,这种方法比哈希比对更加复杂和计算密集,但提供了更高级的图像匹配能力。
代码示例

import os
from PIL import Image
import imagehash
import cv2


class ImageProcess(object):
    def __init__(self, img_path, _type=None):
        """
        初始化函数
        type,1: 平均哈希 aHash, 2: pHash 感知哈希 3:差异哈希 dHash
        img_path: 图片目录
        """
        self._type = _type
        self.img_path = img_path

    def find_duplicates(self):
        """
        哈希对比-对比图片是否相同
        """
        hashes, duplicates = {}, []
        # 遍历图片目录
        image_list = [os.path.join(self.img_path, file_name) for file_name in os.listdir(self.img_path) if
                      file_name.endswith((".png", ".gif", ".jpeg", ".bmp"))]
        for _image in image_list:
            img = Image.open(_image)
            # 计算图像哈希值
            hash_val = imagehash.average_hash(img) if self._type == 1 else imagehash.phash(
                img) if self._type == 2 else imagehash.dhash(img)
            if hash_val in hashes:
                duplicates.append((_image, hashes[hash_val]))
            else:
                hashes[hash_val] = _image
        return duplicates

    @staticmethod
    def match_images(img1, img2):
        """
        匹配图片
        """
        # 初始化orb检测器
        orb = cv2.ORB_create()
        # 提取关键点&描述器
        kp1, de1 = orb.detectAndCompute(img1, None)
        kp2, de2 = orb.detectAndCompute(img2, None)
        # 使用BFMatcher进行匹配
        bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
        matches = bf.match(de1, de2)
        matches = sorted(matches, key=lambda x: x.distance)
        # 依赖于定义的标准,这里只返回匹配特征点的数量
        return len(matches)

    def find_similar_images(self, some_threshold):
        """
        特征匹配-对比图片是否相同
        some_threshold: 相似度阈值
        """
        duplicates = []
        # 加载图片
        image_list = [os.path.join(self.img_path, file_name) for file_name in os.listdir(self.img_path) if
                      file_name.endswith((".png", ".gif", ".jpeg", ".bmp"))]
        images = [(_img, cv2.imread(_img, 0)) for _img in image_list]  # 以灰度模式读取图片
        # 图片两两对比
        for i in range(len(images)):
            for j in range(i + 1, len(images)):
                img1_name, img1 = images[i]
                img2_name, img2 = images[j]
                matches = self.match_images(img1, img2)
                # 假如匹配点超过阈值,则认为图片相似
                if matches > some_threshold:
                    duplicates.append((img1_name, img2_name, matches))
        return duplicates


if __name__ == '__main__':
    img_type = 3
    _path = "XXX"
    img_obj = ImageProcess(_path)
    print(img_obj.find_similar_images(400))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

备注:
1: orb.detectAndCompute 是一种特征检测和描述符计算方法,通常用于图像处理和计算机视觉中。ORB(Oriented FAST and Rotated BRIEF)是一种结合了 FAST 特征检测器和 BRIEF 描述符的方法,它具有旋转不变性和尺度不变性。detectAndCompute 方法结合了特征检测和描述符计算两个步骤,可以在图像中检测出特征点并计算这些特征点的描述符。
具体来说,orb.detectAndCompute(image, mask) 的作用如下:

image 是输入的图像,用于进行特征检测和描述符计算。
mask 是可选参数,用于指定感兴趣区域(ROI),只在这个区域内进行特征检测和描述符计算。
在使用 orb.detectAndCompute 方法时,通常需要先创建一个 ORB 对象,然后调用 detectAndCompute 方法来检测特征点并计算描述符。这个方法常用于图像特征匹配、目标检测、图像拼接等应用中。
2: cv2.ORB_create() 是 OpenCV 中用于创建 ORB 特征检测器对象的函数。ORB(Oriented FAST and Rotated BRIEF)是一种结合了 FAST 特征检测器和 BRIEF 描述符的特征提取算法,具有旋转不变性和尺度不变性,适用于图像特征匹配、目标检测等任务。

import cv2

# 创建 ORB 特征检测器对象
orb = cv2.ORB_create()

# 读取输入图像
image = cv2.imread('image.jpg')

# 将图像转换为灰度图
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用 ORB 对象检测特征点并计算描述符
keypoints, descriptors = orb.detectAndCompute(gray_image, None)

# 绘制特征点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None, color=(0, 255, 0), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# 显示图像
cv2.imshow('Image with keypoints', image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在上面的示例中,首先使用 cv2.ORB_create() 创建了一个 ORB 特征检测器对象,然后读取输入图像并将其转换为灰度图像。接着使用 ORB 对象的 detectAndCompute() 方法检测图像中的特征点并计算描述符,最后将特征点绘制在图像上并显示出来。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/957437
推荐阅读
相关标签
  

闽ICP备14008679号