2025年3月18日 星期二 甲辰(龙)年 月十七 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 数据结构与算法

谈谈相似图片搜索

时间:11-03来源:作者:点击数:51

先说一下搜索的原理,其实就是不管你搜索什么,都是将你要搜的东西提取出特征值,然后按照特征值比较相似度,按照相似度排序呈献给用户就可以了,所以总共来说需要解决两个问题,一个是如何取得特征值,一个是如何计算相似度。

首先说特征值,特征值可以用图片的颜色比例来,比如python用PIL中的histogram函数就可以得到颜色分布

这幅图的颜色分布直方图是这样的

通过这样我们就得到了一个图像的特征值,这种方法是得到的颜色的分配,还有另一种方式得到的则是图像的内容特征。

基本想法是将图片弄成8*8的小图片这样摒弃掉细节内容,将图片灰度,根据灰度确定一个阈值,然后转换成01矩阵,其他的内容都好说,简要说一下确定阈值的方法,有一个知名的方法叫OSTU,又叫大律法,他的想法是使得分配后的方差尽可能的大。再说的具体点就是

对图像Image,记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。 图像的总平均灰度为:u=w0*u0+w1*u1。从最小灰度值到最大灰度值遍历t,当t使得值g=w0*(u0-u)2+w1* (u1-u)2 最大时t即为分割的最佳阈值。 

下面是具体的程序:

  • #coding=utf-8
  • import Image,ImageDraw
  • ret = {}
  • def twoValue(image,G):
  • for y in xrange(0,image.size[1]):
  • for x in xrange(0,image.size[0]):
  • g = image.getpixel((x,y))
  • if g > G:
  • ret[(x,y)] = 1
  • else:
  • ret[(x,y)] = 0
  • def OtsuGray(image):
  • hist = image.histogram()
  • totalH = 0
  • for h in range(0,256):
  • v =hist[h]
  • if v == 0 : continue
  • totalH += v*h
  • width = image.size[0]
  • height = image.size[1]
  • total = width*height
  • v = 0
  • gMax = 0.0
  • tIndex = 0
  • total0 = 0.0
  • total1 = 0.0
  • n0H = 0.0
  • n1H = 0.0
  • for t in range(1,255):
  • v = hist[t-1]
  • if v == 0: continue
  • total0 += v
  • total1 = total - total0
  • n0H += (t-1)*v
  • n1H = totalH - n0H
  • if total0 > 0 and total1 > 0:
  • u0 = n0H/total0
  • u1 = n1H/total1
  • w0 = total0/total
  • w1 = 1.0-w0
  • uD = u0-u1
  • g = w0 * w1 * uD * uD
  • if gMax < g:
  • gMax = g
  • tIndex = t
  • return tIndex
  • def saveImage(filename,size):
  • image = Image.new("1",size)
  • draw = ImageDraw.Draw(image)
  • for x in xrange(0,size[0]):
  • for y in xrange(0,size[1]):
  • draw.point((x,y),ret[(x,y)])
  • image.save(filename)
  • def handle(filename,outputname):
  • im = Image.open(filename)
  • im = im.convert('L')
  • otsu = OtsuGray(im)
  • twoValue(im,otsu)
  • saveImage(outputname,im.size)
  • if __name__=='__main__':
  • handle('111.jpg','temp.jpg')

这样转换后的图片是这样子的

得到了特征值后就是计算相似度,比如第二种得到特征值的方法,我们只需将得到的矩阵进行异或,异或后,1越少的越相近,而对于第一种特征值最普遍的方法就是把他看成向量,然后想想向量的点乘,计算两个向量的夹角,夹角越小越相似,cos夹角=(a1*b1+a2*b2+a3*b3....)/(|a|*|b|),当然了,还有其他得到相似度的计算方法,这个就是具体问题具体对待了呢。

ps:话说根据本文的方法你也可以进行验证码识别的一些邪恶举动呢。。。但是不要做坏事哦~

pss:这篇文章介绍一些有趣的图像算法,有兴趣的童鞋可以围观

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门