先说一下搜索的原理,其实就是不管你搜索什么,都是将你要搜的东西提取出特征值,然后按照特征值比较相似度,按照相似度排序呈献给用户就可以了,所以总共来说需要解决两个问题,一个是如何取得特征值,一个是如何计算相似度。
首先说特征值,特征值可以用图片的颜色比例来,比如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|),当然了,还有其他得到相似度的计算方法,这个就是具体问题具体对待了呢。