您当前的位置:首页 > 电脑百科 > 程序开发 > 算法

比较图片相似算法

时间:2019-10-16 10:55:03  来源:  作者:

概述

一般情况下, 图片相似算法分为三种

  • 均值Hash算法
  • 差异值hash算法
  • 感知hash算法

其实三个算法差不多. 我们以均值hash算法为例, 算法的步骤如下:

  1. 缩放为n*n的图片
  2. 去色, 获取灰度图
  3. 得到hash指纹
  4. 比较hash指纹的汉明距离, 得到相似值

上面算法的不同, 主要是得到hash指纹的算法不同

均值hash算法

我们举例说明. 原图如下:

比较图片相似算法

 

缩放为8*8的图片

代码:

img = cv2.resize(img, (8, 8), interpolation=cv2.INTER_CUBIC)
复制代码

缩放结果

比较图片相似算法

 

去色

代码

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
复制代码

结果:

比较图片相似算法

 

计算灰度平均值

 # 计算灰度平均值
 for i in range(8):
 for j in range(8):
 s = s + gray_img[i, j]
 avg = s / 64
复制代码

计算结果为176

计算Hash指纹

计算方法为, 如果该点灰度值大于平均灰度值, 这为1, 否则为0, 代码如下:

 # 如果值大于灰度值, 则为1, 否则为0. 生成hash指纹
 for i in range(8):
 for j in range(8):
 if gray_img[i, j] > avg:
 hash_str = hash_str + '1'
 else:
 hash_str = hash_str + '0'
复制代码

计算汉明距离

汉明距离: 在信息论中,两个等长字符串之间的汉明距离(英语:Hamming distance)是两个字符串对应位置的不同字符的个数。 代码:

def cmp_hash(hash_1, hash_2):
 # 计算汉明距离
 n = 0
 if len(hash_1) != len(hash_2):
 return -1
 for i in range(len(hash_1)):
 if hash_1[i] != hash_2[i]:
 n = n + 1
 return n
复制代码

差异值hash算法

前面缩放, 置灰, 计算汉明距离等和平均值hash算法一样, 区别在于计算hash指纹的算法不同. 该处算法为: 如果前一个像素大于后一个像素的灰度值, 则为1, 否则为0. 完整的算法如下:

# 差值感应hash
def b_hash(img):
 # 缩放到8*8的图片
 img = cv2.resize(img, (9, 8), interpolation=cv2.INTER_CUBIC)
 # 得到灰度图
 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 hash_str = ''
 # 如果前一个像素比后一个大, 则为1, 否则为0. 生成hash指纹
 for i in range(8):
 for j in range(8):
 if gray_img[i, j] > gray_img[i, j + 1]:
 hash_str = hash_str + '1'
 else:
 hash_str = hash_str + '0'
 return hash_str
复制代码

感知Hash算法

前面两种比较图片相似的算法很好理解. 感应Hash算法的思想与之不同. 我们换一种角度来看待一张图片. 一个图片其实就是二维的信息图谱, 有各种频率的变化, 频率高的地方代表颜色的变换比较大, 例如轮廓部分. 我们可以利用DCT变换(离散余弦变换)得到频域图. 比较低频部分(为什么要比较低频部分?) 是否相似就可以了.

原图还是上面的原图. 我们先进行缩放, 缩放为32*32的部分

比较图片相似算法

 

灰度处理

比较图片相似算法

 

进行DCT变换

比较图片相似算法

 

我们拿到左上角的8*8的区域, 根据平均值hash算法比较这个灰度图的汉明距离

完整的代码如下:

# 感知hash
def p_hash(img):
 # 缩放到32 * 32
 img = cv2.resize(img, (32, 32), interpolation=cv2.INTER_CUBIC)
 cv2.imwrite("bb.jpg", img)
 # 得到灰度图
 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 gray_img = gray_img.astype(np.float32)
 cv2.imwrite("cc.jpg", gray_img)
 # 进行离散余弦变换, 目的是将低频部分放到左上角
 img = cv2.dct(gray_img)
 cv2.imwrite("dd.jpg", img)
 # 得到左上角8*8 的频率图
 img = img[0:8, 0:8]
 avg = 0
 # 与得到低频图的平均灰度
 hash_str = ''
 for i in range(8):
 for j in range(8):
 avg += img[i, j]
 avg = avg / 64
 # 如果低频图的像素值大于平均灰度, 则为1, 否则为0. 依次生成hash指纹
 for i in range(8):
 for j in range(8):
 if img[i, j] > avg:
 hash_str = hash_str + '1'
 else:
 hash_str = hash_str + '0'
 return hash_str
复制代码

参考文献:K码农-http://kmanong.top/kmn/qxw/form/home?top_cate=28



Tags:算法   点击:()  评论:()
声明:本站部分内容来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除,谢谢。
▌相关评论
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
▌相关推荐
sensor、codec、display device都是基于pixel的,高分辨率图像能呈现更多的detail,由于sensor制造和chip的限制,我们需要用到图像插值(scaler/resize)技术,这种方法代价小,使用方便...【详细内容】
2020-11-12   算法  点击:(4)  评论:(0)  加入收藏
1、引言今天的运气不是很好,再加上项目的压力。准备停止学习一周,等把项目这一关过了,再继续深入学习分享算法。后来吧今天遇到的事情都比较郁闷,也无心情继续开发项目。便想转...【详细内容】
2020-11-12   算法  点击:(2)  评论:(0)  加入收藏
一、介绍及原理1.1 简介哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。比如Java字符串的hashCode()就是哈希算法,输出是...【详细内容】
2020-11-12   算法  点击:(4)  评论:(0)  加入收藏
今天我们来和大家聊聊随机数。大家如果学过编程对于随机数应该都不陌生,应该或多或少都用到过。再不济我们每周的抽奖都是用随机数抽出来的,我们用随机数的时候,往往都会加一个...【详细内容】
2020-11-11   算法  点击:(3)  评论:(0)  加入收藏
我们先从常见的拜占庭将军问题中理解一下什么是共识。 拜占庭将军问题 拜占庭位于如今的土耳其的伊斯坦布尔,是东罗马帝国的首都。由于当时拜占庭罗马帝国国土辽阔,为了防御目...【详细内容】
2020-11-11   算法  点击:(4)  评论:(0)  加入收藏
linux内核调度程序很先进很强大,管理你的LINUX上跑的大量的乱七八糟的进程,同时还保持着对用户操作的高灵敏响应,如果可能,为什么不把这种思想放到自己的应用程序里呢?或者,有没...【详细内容】
2020-11-11   算法  点击:(1)  评论:(0)  加入收藏
背景“生产者和消费者模型” 是多线程通信的典型案例,本章节将利用前一节的锁和条件队列的知识,来实现一个完整的有界缓冲区,并创建多个线程访问该有界缓冲区,模拟生产者提供数...【详细内容】
2020-11-10   算法  点击:(2)  评论:(0)  加入收藏
1 什么是LRULRU(Least recently used)最近最少使用,它的核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。因此 LRU 算法会根据数据的历史访问记录来进行排序,如...【详细内容】
2020-11-09   算法  点击:(2)  评论:(0)  加入收藏
题目给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。示例 1:输入: 1->1->2输出: 1->2示例 2:输入: 1->1->2->3->3输出: 1->2->3思路这是一个简单的问题,仅测试...【详细内容】
2020-11-09   算法  点击:(3)  评论:(0)  加入收藏
如何进行算法分析呢?最简单方法是分别运行解决同一个问题的两个算法进行比较,但这样做法在很多时候并不理想。面对这样的困难迫使我们求助于数学工具,虽然我们不能对一个还没...【详细内容】
2020-11-08   算法  点击:(0)  评论:(0)  加入收藏
前言LRU算法和LFU算法是属于页面置换的一种算法,或者更通俗的说,就是缓存如何淘汰的一种策略。我们通常在设计一个系统的时候,由于数据库的读取速度远小于内存的读取速度,所以为...【详细内容】
2020-11-04   算法  点击:(2)  评论:(0)  加入收藏
对监控领域的目标跟踪方法以及面临的挑战进行了一个介绍,是一个很好的了解目标跟踪领域的“是什么”和“为什么”问题的文章。...【详细内容】
2020-11-03   算法  点击:(5)  评论:(0)  加入收藏
人脸检测是计算机视觉中的老话题,应用广泛,研究者众多,业界不仅在向着更准的检测算法前进,轻量级检测人脸算法也成为应用中的宠儿。本文总结了近年轻量级人脸检测算法的开源实现...【详细内容】
2020-11-01   算法  点击:(0)  评论:(0)  加入收藏
在回溯算法:求组合问题!中,我们通过回溯搜索法,解决了n个数中求k个数的组合问题。文中的回溯法是可以剪枝优化的,本篇我们继续来看一下题目77. 组合。链接:https://leetcode-cn.co...【详细内容】
2020-10-29   算法  点击:(6)  评论:(0)  加入收藏
提到hash,相信大多数同学都不会陌生,之前很火现在也依旧很火的技术区块链背后的底层原理之一就是hash,下面就从hash算法的原理和实际应用等几个角度,对hash算法进行一个讲解。1...【详细内容】
2020-10-23   算法  点击:(7)  评论:(0)  加入收藏
本文的主要目标是让您对深度学习领域有一个整体了解,并帮助您了解每种特定情况下应使用的算法。神经网络:基础神经网络是一个具有相互连接的节点的计算系统,其节点的工作方式...【详细内容】
2020-10-21   算法  点击:(7)  评论:(0)  加入收藏
图形结构是一种比树形结构更复杂的非线性结构。在树形结构中,结点间具有分支层次关系,每一层上的结点只能和上一层中的至多一个结点相关,但可能和下一层的多个结点相关。而在图形结构中,任意两个结点之间都可能相关,即结点...【详细内容】
2020-10-21   算法  点击:(6)  评论:(0)  加入收藏
今天选择的算法题是来自contest 1407比赛的C题,这题全场通过6700余人。通过的人数虽然多,但是这题真的不简单,想出算法来不太容易。抛开难度不提,这道题非常非常有意思,老实说这...【详细内容】
2020-10-19   算法  点击:(5)  评论:(0)  加入收藏
算法和数据结构一直以来都是程序员的基本内功,可以说没有数据结构的基础建设和算法加持,也就没有这将近八十年的信息革命时代。数据结构可以看作是算法实现的容器,通过一系列特...【详细内容】
2020-10-14   算法  点击:(4)  评论:(0)  加入收藏
LRU的英文全称是Least Recently Used,也即最不经常使用。我们看着好像挺迷糊的,其实这个含义要结合缓存一起使用。对于工程而言,缓存是非常非常重要的机制,尤其是在当下的互联网...【详细内容】
2020-10-14   算法  点击:(9)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条