关于相似图片搜索

关于相似图片搜索

关于相似图片搜索

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

首先说特征值,特征值可以用图片的颜色比例来,比如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即为分割的最佳阈值。

下面是具体的程序:

  1. #coding=utf-8  
  2. import Image,ImageDraw  
  3. ret =  { }
  4. def twoValue (image,G ):  
  5.      for y  in  xrange ( 0,image. size [ 1 ] ):  
  6.          for x  in  xrange ( 0,image. size [ 0 ] ):  
  7.             g = image. getpixel ( (x,y ) )  
  8.              if g  > G:  
  9.                 ret [ (x,y ) ] =  1  
  10.              else:  
  11.                 ret [ (x,y ) ] =  0
  12. def OtsuGray (image ):  
  13.     hist = image. histogram ( )    
  14.     totalH =  0  
  15.      for h  in  range ( 0, 256 ):  
  16.         v =hist [h ]  
  17.          if v ==  0 :  continue  
  18.         totalH += v *h  
  19.     width  = image. size [ 0 ]  
  20.     height = image. size [ 1 ]  
  21.     total  = width *height  
  22.     v =  0  
  23.     gMax =  0.0  
  24.     tIndex =  0  
  25.     total0 =  0.0  
  26.     total1 =  0.0  
  27.     n0H   =  0.0  
  28.     n1H   =  0.0  
  29.      for t  in  range ( 1, 255 ):  
  30.         v = hist [t -1 ]  
  31.          if v ==  0continue          
  32.         total0 += v
  33.         total1 = total - total0
  34.         n0H +=  (t -1 ) *v
  35.         n1H = totalH - n0H
  36.          if total0  >  0  and total1  >  0:
  37.             u0 = n0H/total0
  38.             u1 = n1H/total1
  39.             w0 = total0/total
  40.             w1 =  1.0-w0
  41.             uD = u0-u1
  42.             g = w0  * w1  * uD  * uD
  43.              if gMax  < g:  
  44.                 gMax   = g  
  45.                 tIndex = t                
  46.      return tIndex
  47. def saveImage (filename,size ):  
  48.     image = Image. new ( "1",size )  
  49.     draw = ImageDraw. Draw (image )  
  50.      for x  in  xrange ( 0,size [ 0 ] ):  
  51.          for y  in  xrange ( 0,size [ 1 ] ):  
  52.             draw. point ( (x,y ),ret [ (x,y ) ] )  
  53.     image. save (filename )
  54. def handle (filename,outputname ):
  55.     im = Image. open (filename )
  56.     im = im. convert ( 'L' )
  57.     otsu = OtsuGray (im )
  58.     twoValue (im,otsu )
  59.     saveImage (outputname,im. size )
  60. if __name__== '__main__':
  61.     handle ( '111.jpg', 'temp.jpg' )

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

关于相似图片搜索

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

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

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

本文转载自:http://www.isnowfy.com/similar-image-search/

你可能感兴趣的:(图片)