相似图片搜索

  前几天在伯乐网上看到有转载相似图片搜索的文章,其实它的方法很简单,就是一篇图片,先做灰度化,resize,01化处理,在判断。出于专业敏感,我想是不是可以利用视频或者图像编码中的DCT变换,利用少量的空间存储大部分的有效信息,然后再比较,网上搜了搜,果然有这样的算法:phash

  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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One2zeror

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值