相似图片搜索
2015-08-09 16:44
288 查看
前几天在伯乐网上看到有转载相似图片搜索的文章,其实它的方法很简单,就是一篇图片,先做灰度化,resize,01化处理,在判断。出于专业敏感,我想是不是可以利用视频或者图像编码中的DCT变换,利用少量的空间存储大部分的有效信息,然后再比较,网上搜了搜,果然有这样的算法:phash
phash算法有很多种,这里介绍一种基于DCT的phash算法。
图片指纹生成方法:
图片灰度化
图片缩放到32x32
DCT变换处理
保留最左上部的8x8的DCT系数(图片信息最多部分)
计算中值
生成64位指纹,跟中值比较,0表示小于中值,反之为1
对图片库中的图片按上面方法生成指纹,跟搜寻图片对比,相同指纹比特大于一定阈值,认为相似。
下面是一个简单的python实现,我这里是将图片缩放到了64x64,DCT为16x16:
包子姐最近上了头条,就用菲吧里的图做个测试吧:
搜索图片
搜索结果(4/52)
phash算法有很多种,这里介绍一种基于DCT的phash算法。
图片指纹生成方法:
图片灰度化
图片缩放到32x32
DCT变换处理
保留最左上部的8x8的DCT系数(图片信息最多部分)
计算中值
生成64位指纹,跟中值比较,0表示小于中值,反之为1
对图片库中的图片按上面方法生成指纹,跟搜寻图片对比,相同指纹比特大于一定阈值,认为相似。
下面是一个简单的python实现,我这里是将图片缩放到了64x64,DCT为16x16:
import io import os from PIL import Image import numpy as np from scipy import fftpack import urllib2 #import IPython import re #image_url = 'http://imgsrc.baidu.com/forum/w%3D580/sign=bfe6fdf5fddcd100cd9cf829428a47be/1a3a1f30e924b8992d202ec06b061d950a7bf628.jpg' base_image_url = 'http://imgsrc.baidu.com/forum/w%3D580/sign=41563ba1053b5bb5bed720f606d2d523/2bdabc3eb13533faebe9a924aed3fd1f41345b5a.jpg' size = (64,64) subsize = 16 def get_image_from_url(image_url): image_fd = urllib2.urlopen(image_url) image_file = io.BytesIO(image_fd.read()) image = Image.open(image_file) #image.show() return image def preproc_image(image, size=(32, 32)): """ 图片预处理 """ img_color = image.resize(size, Image.ANTIALIAS) #如果用image.thumbnail() 将保持长宽比 img_grey = img_color.convert('L') #img_grey.show() img_grey_array = np.array(img_grey, dtype=np.float) return img_grey_array def get_2d_dct(image_array): """ 2D DCT变换 """ return fftpack.dct(fftpack.dct(image_array.T, norm='ortho').T, norm='ortho') def proc_image(image, size=(32, 32), subsize=8): #image = get_image_from_url(image_url) image_grey_array = preproc_image(image, size) dct_array = get_2d_dct(image_grey_array) dct_subarray = dct_array[:subsize,:subsize] dct_subarr_fabs = np.fabs(dct_subarray) print dct_subarr_fabs dct_subaverage = np.mean(dct_subarr_fabs) dct_subfinal = np.greater_equal(dct_subarr_fabs, dct_subaverage*np.ones(dct_subarr_fabs.shape)) return dct_subfinal base_image = get_image_from_url(base_image_url) base_image.save("imageToFind.png",'PNG') base_dct_subfinal = proc_image(base_image, size , subsize) #######################You may change here############### #baseurl = 'http://tieba.baidu.com/p/3833419819/' #请自行添加查找网页地址 baseurl = 'http://tieba.baidu.com/p/3942417083/' format = '(png|bmp|jpg|jpeg|gif|PNG|BMP|JPG|JPEG|GIF)' #图片格式,可自行添加 ######################################################### #打开页面 page = urllib2.urlopen(baseurl) # 读取包含HTML源码内容的页面信息 page_inform = page.read() # 获取图片资源列表 list_of_res = re.findall(r'src="(https?://[^<>]*?\.%s)"' % format, page_inform) # 去除重复的图片资源 list_of_res = list(set(list_of_res)) imgFindedCount = 0 imgDoneCount = 0 # 根据图片资源列表逐个搜寻 for res in list_of_res: image_url = res[0] if image_url[0:4] != 'http': image_url = baseurl+image_url #print image_url image = get_image_from_url(image_url) imgDoneCount = imgDoneCount + 1 #image.save("images/image%d.png" % imgDoneCount, "PNG") if(np.abs(image.size[0]- base_image.size[0])>100 or np.abs(image.size[1]- base_image.size[1])>100): print "第%d张图片不匹配" % imgDoneCount continue dct_subfinal = proc_image(image, size, subsize) #image.show() dct_subfinal = np.logical_xor(base_dct_subfinal, dct_subfinal) image_distance = np.count_nonzero(dct_subfinal) print image_distance print image_distance if(image_distance < 50): #image.show() imgFindedCount = imgFindedCount + 1 image.save("imageFinded%d.png" % imgFindedCount, "PNG") print "第%d张图片匹配,已找到%d张相似图片~~" % (imgDoneCount,imgFindedCount) #break else: print "第%d张图片不匹配" % imgDoneCount print "搜索完成^^,共找到%d张相似图片~~" % imgFindedCount
包子姐最近上了头条,就用菲吧里的图做个测试吧:
搜索图片
搜索结果(4/52)
相关文章推荐
- HDU4565 So Easy!(数学+矩阵快速幂)
- HDU 1394 Minimum Inversion Number
- BZOJ3459 : Bomb
- C++ class与内存
- hdu 3593 分类: hdu 2015-0...
- Grep用法
- 通过SQLServer的数据库邮件来发送邮件
- GC垃圾收集算法
- LeetCode(20)Valid Parentheses
- LeetCode(141)(142) Linked List Cycle I II
- hdu 3593
- windowsphone8.1学习笔记之应用数据(二)
- hdu 3593 分类: hdu 2015-08-09 16:43 12人阅读 评论(0) 收藏
- LeetCode(20)Valid Parentheses
- leetcode_242——Valid Anagram (字典法)
- 第三周工作周报
- java synchronized静态同步方法与非静态同步方法,同步语句块
- ListView上拉加载更多
- Java回顾之I/O
- php框架laravel学习 二 (数据库建立迁移与建模)