使用OpenCV,Phthon进行图像哈希处理的一个重要应用是去除重复的图像;

当你有多个相册的图片,进行合并时,so boring,有一些图片是重复的,肉眼来看太难删除了。

图像哈希可以帮助你完美的解决这个问题,找到完全相同的图片,只保留一张,删除其他的。

图像哈希(也称为感知哈希)是基于图像的视觉内容构造哈希值的过程。我们将图像哈希用于CBIR,近重复检测和反向图像搜索引擎。

1. 图像哈希的原理

(1)检查图像内容
(2)构造一个哈希值,该哈希值根据图像的内容唯一地标识输入图像

图像哈希的最重要的一个应用是:反向图像搜索引擎。

2. 为什么md5,sha-1不起作用?

将一张图片有250250缩放到500500,图像没有变化,但计算出来的md5值变了。原因在于:密码哈希算法的本质:更改文件中的单个位将导致不同的哈希。

在图像哈希/感知哈希情况下,我们实际上希望相似的图像也具有相似的哈希值。 这也是根本原因。

解决办法: 使用差分哈希(Difference Hash 简称dHash);

3. 差异哈希

(1)转为灰度图(可以更快运算,匹配相同但色彩空间稍有改变的图像);
(2)忽略宽高比的缩放图像至9 * 8;
(3)9 * 8计算相邻行之间相邻像素的差值,得到8 * 8;
(4)计算哈希值(x>p(x+1) =1 : 0);

4. 差异哈希的好处

(1)如果输入图像只是宽高比发生变化,图像哈希不会改变;
(2)只是调整亮度或对比度将不会更改哈希值,或者只会对其稍有更改,以确保哈希值紧密地靠在一起;
(3)差异哈希速度非常快;

5. 对比差异哈希的值

  • 使用汉明距离对比俩个哈希的值;
  • 汉明距离为零的两个哈希值意味着两个哈希值是相同的(因为没有不同的位),并且两个图像是相同的/在感知上也相似。

6. 应用差异哈希解决实际问题

问题:整理照片常遇到的问题,文件夹haystack,文件夹needle中有许多子目录,包含很多照片。
目标:判断needle中有哪些目录的哪些照片没有 在haystack;

# python hash_and_search.py --haystack haystack --needles needles# 导入必要的包
from imutils import paths
import argparse
import time
import sys
import cv2
import os# 差分Hash算法(相邻列的相邻像素相减  由9*8 相减得到 8*8 64位哈希值)
def dhash(image, hashSize=8):# 缩放图像,多增加一列,以后续进行水平梯度计算resized = cv2.resize(image, (hashSize + 1, hashSize))# 水平方向,计算相邻的行之间的差值diff = resized[:, 1:] > resized[:, :-1]# 转换不同图像为hashreturn sum([2 ** i for (i, v) in enumerate(diff.flatten()) if v])# 构建命令行参数
# --haystack 大文件夹
# --needle 小文件夹
# 目标: 检查needle中的每个图像是否在haystack中,已存在的删除,不存在的保留
ap = argparse.ArgumentParser()
ap.add_argument("-a", "--haystack", required=True,help="dataset of images to search through (i.e., the haytack)")
ap.add_argument("-n", "--needles", required=True,help="set of images we are searching for (i.e., needles)")
args = vars(ap.parse_args())# 获取needle、haystack文件夹总的所有图片文件
print("[INFO] computing hashes for haystack...")
haystackPaths = list(paths.list_images(args["haystack"]))
needlePaths = list(paths.list_images(args["needles"]))# 移除文件中的\\ 或者空格
# Windows操作系统使用\分隔路径
# 在Unix系统使用/时分隔路径
if sys.platform != "win32":haystackPaths = [p.replace("\\", "") for p in haystackPaths]needlePaths = [p.replace("\\", "") for p in needlePaths]# 获取needle的子目录 初始化字典(映射文件名和hash值)
BASE_PATHS = set([p.split(os.path.sep)[-2] for p in needlePaths])
haystack = {}  # 文件名与hash值的映射字典
start = time.time()# 循环遍历haystack路径
for p in haystackPaths:# 从磁盘加载图片image = cv2.imread(p)# 如果image为None,跳过...if image is None:continue# 转换图像为灰度图,并计算hash值image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)imageHash = dhash(image)# 更新haystack字典l = haystack.get(imageHash, [])l.append(p)haystack[imageHash] = l# 显示haystack字典更新的耗时,开始甲酸needle图像的hash值
print("[INFO] processed {} images in {:.2f} seconds".format(len(haystack), time.time() - start))
print("[INFO] computing hashes for needles...")# 遍历needle路径的图像
for p in needlePaths:# 加载图片image = cv2.imread(p)# 图像为None,跳过...if image is None:continue# 转换为灰度图,计算hash值image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)imageHash = dhash(image)# 获取所有匹配该hash值的图像matchedPaths = haystack.get(imageHash, [])# 遍历所有匹配的图像路径for matchedPath in matchedPaths:# 提取图片的子文件夹路径b = p.split(os.path.sep)[-2]# 如果needle路径的基本路径包含子目录,if b in BASE_PATHS:BASE_PATHS.remove(b)# 显示路径以检查
print("[INFO] check the following directories...")
# 循环遍历子目录并打印照片
for b in BASE_PATHS:print("[INFO] {}".format(b))

使用OpenCV,Python进行图像哈希(差分哈希 dHash)处理相关推荐

  1. openCV—Python(6)—— 图像算数与逻辑运算

    openCV-Python(6)-- 图像算数与逻辑运算 一.函数简介 1.add-图像矩阵相加 函数原型:add(src1, src2, dst=None, mask=None, dtype=Non ...

  2. OpenCV python 提取图像内的三色

    OpenCV python 提取图像内的三色 原图 [opencv.jpg] import cv2 import numpy as npdef main():# 1.导入图片img_src = cv2 ...

  3. python opencv 图像切割_【OpenCV+Python】图像的基本操作与算术运算

    图像的基本操作 在上个教程中,我们介绍了使用鼠标画笔的功能.本次教程,我们将要谈及OpenCV图像处理的基本操作. 本次教程的所有操作基本上都和Numpy相关,而不是与OpenCV相关.要使用Open ...

  4. OpenCV—Python PyLibTiff_psd 图像基本操作以及图像格式转换

    文章目录 一.图片 读.写.显示.属性查看 libtiff 包装器 Python 模块 opencv 模块 PIL 模块 直接修改图片格式 大(分辨率大)图片缩小 与上面代码同效 二.PSD图像读取与 ...

  5. opencv+python实现图像的增强与合成(人像迁移)

    代码链接:图像的增强与合成 最近做了一个小实验,内容是图像的增强与合成,觉着挺有意思,记录一下. 首先效果是这样的: 利用Python和Opencv算法,实现下述功能: 1. 准备本人在纯色背景前的照 ...

  6. OpenCV+python:图像梯度

    1,图像梯度的概念 梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(无论是横向的.纵向的.斜方向的等等),所需要的是一个核模板.模板的不同结果也不同.所以能够看到,全部的这些个算子函数,归 ...

  7. OpenCV+python:图像金字塔

    1,图像金字塔的概念 图像金字塔是一种以多分辨率来解释图像的有效但概念简单的结构.应用于图像分割,机器视觉和图像压缩.一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图 ...

  8. OpenCV+python:图像二值化

    1,图像二值化概念及方法 一个像素点的颜色是由RGB三个值来表现的,所以一个像素点矩阵对应三个颜色向量矩阵,分别是R矩阵,G矩阵,B矩阵,它们也都是同样大小的矩阵. 在图像处理中,用RGB三个分量(R ...

  9. python的image读取的图片是什么类型的-opencv python 读取图像/显示图像/保存图像...

    以前也用过opencv, 不过都是按需使用, 掌握的知识很零散, 这次希望能够系统学习opencv-python 本文直接从Gui Features开始. 1 读取图片 使用cv2.imread()函 ...

  10. opencv mat release thrown_【OpenCV+Python】图像与视频处理入门

    图像处理入门 之前我们已经讲过了OpenCV在各个平台上安装的方法了,从今天开始,正式进入实战部分.首先我们需要做的就是如何读取图像并显示出来,这是图像处理的最基本的部分. 首先我们来了解几个函数. ...

最新文章

  1. Eclipse常用快捷键、常用设置、常见问题等
  2. linux kernel使用技巧
  3. 不要把时间画在抽奖上。。。去学习吧。。。
  4. DirectSound学习笔记(3):协作级别
  5. 我的世界梦之边缘5服务器在维护吗,8月5日服务器例行维护公告(已完成)
  6. Boost:ping的测试程序
  7. java中类型的相互转化_Java中的数据类型及相互转换方法
  8. 2016谷歌官方最新eclipse工程导入studio,以前方式全部废弃。不能再使用。
  9. 关于 SAP 电商云 Spartacus UI 访问 b2b site 的权限问题
  10. FastJson的常用操作
  11. webgl 基础渲染demo_WebGL + ThreeJS 实现实时水下焦散 Part 1
  12. Linux系统编程——僵尸的模拟以及僵尸进程的预防
  13. 下次偶转贴贴子时得加上转贴才行~~~
  14. ant jsch.jar - 一个错误及解决办法
  15. CISP 和 NISP差别一览
  16. C语言中动态库/静态库的创建和使用
  17. Xss漏洞原理分析及简单的讲解
  18. 中国为什么要买美国国债
  19. Epoll原理深入分析
  20. windows系统下MySQL中遇到1045问题

热门文章

  1. 2021年大数据Flink(一):乘风破浪的Flink-Flink概述
  2. Docker核心技术之Dockerfile
  3. Cocos Creator 预制的使用模板(一般用于UI)
  4. Fragment 使用 show 和 hide 的方式实现切换 以及切换的时候Fragment 生命周期
  5. 文本类控件(EditView 的介绍)
  6. 解剖JavaScript中的null和undefined
  7. ng new ng-pro 报错(创建angular6项目报错)
  8. centos7+ansible自动化工具使用
  9. 【总结】sqli-labs Less(1-35) 小结
  10. HttpServletResponse对象(一)