使用HOG+卡方距离的方法实现图片检索(python写)

在上一篇的文章中,使用HOG特征提取了图片的特征,本篇文章则加上卡方距离的方法实现相似图片的检索。

前言

使用150张图片,包括airplane、beach、desert、island和sea_ice各50张图片进行测试。

第一步,获取图片特征

获取150张图片的特征,并且保存到index.csv文件夹中。首先打开一个文件,并将此文件命名为getfeats.py。

#coding:utf-8
import numpy as np
from skimage.feature import hog
from PIL import Image


size = 256

#获取图片列表
def get_image_list(filePath,nameList):
    img_list = []
    for name in nameList:
        temp = Image.open(filePath+name)
        img_list.append(temp.copy())
        temp.close()

    return img_list


def get_feat(image_list,name_list,size):
    i = 0
    for image in image_list:
        #print(name)
        try:
            #这里是彩色图片,所以是3
            image = np.reshape(image, (size, size, 3))
            #print(image)
        except:
            print (name_list[i])
            continue
        gray = rgb2gray(image)/255.0
        #根据自己的数据集进行修改
        fd = hog(gray, orientations=9, pixels_per_cell=[8,8], cells_per_block=[4,4], visualize=False, transform_sqrt=True,block_norm='L2-Hys')
        fd = np.concatenate((fd, [name_list[i]]))
        i = i+1
        #print(fd)

        output = open('index.csv', "a")  #a是添加数据,如果是重新写入用w
        output.write("%s,%s\n" % (fd[-1], ",".join(fd[:-2])))
        output.close()


#变为灰度图片
def rgb2gray(im):
    gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140
    return gray


#获得图片名称
def get_name_label(file_path):
    #print(file_path)
    name_list = []
    label_list = []
    with open(file_path) as f:
        for line in f.readlines():
            name_list.append(line.split(' ')[0])
            label_list.append(line.split(' ')[1]) #此处对于此代码是多余的,以后可能会用得上
            #print(name_list,label_list)
    return name_list,label_list



if __name__ == '__main__':
    train_name,train_label = get_name_label('./image/train.txt')
    train_image = get_image_list('./image/',train_name)
    get_feat(train_image,train_name,size)

第二步,定义卡方距离

需要一个新的文件夹 ,将其命名为searcher.py。

#coding:utf-8
import getfeat
import numpy as np
import csv



def search( queryFeatures, limit = 5):
        # initialize our dictionary of results
    results = {}

        # 打开索引并进行读取
    with open('index.csv') as f:
            # 初始化CSV阅读器
        reader = csv.reader(f)

            # 循环遍历索引中的每一行
        for row in reader:
            #解析图像ID和特征,然后计算索引中的要素与查询要素之间的卡方距离
            features = [float(x) for x in row[1:]]
            d = chi2_distance(features, queryFeatures)

            #既然我们有两个特征向量之间的距离,我们可以更新结果字典
            #关键词是索引中的当前图像ID,值是我们刚刚计算的距离,
            #索引中图像的“相似”程度是我们的查询结果
            results[row[0]] = d

            #关闭阅读器
        f.close()

        #对我们的结果进行排序,以便缩小距离(即更相关的图像位于列表的前面)。值越小,相似度越高
    results = sorted([(v, k) for (k, v) in results.items()])

        #返回我们(有限)的结果
    return results[:limit]

def chi2_distance( histA, histB, eps = 1e-10):
        #计算卡方距离
    d = 0.5 * np.sum([((a - b) ** 2) / (a + b + eps)
        for (a, b) in zip(histA, histB)])

        #返回卡方距离
    return d

第三步,将查询图片进行特征提取

打开一个文件,将其命名为geatfeat.py.

#coding:utf-8
import numpy as np
from PIL import Image
from skimage.feature import hog


size = 256


#提取图片特征
def get_feat():
    image = 'beach_001.jpg'
    image = Image.open(image)
    #image.show()
    image = np.reshape(image, (size, size, 3))
    #print(image)

    gray = rgb2gray(image)/255.0
    #这句话可以根据自己的图片集进行修改
    fd = hog(gray, orientations=9, pixels_per_cell=[8,8], cells_per_block=[4,4], visualize=False, transform_sqrt=True,block_norm='L2-Hys')
    #print(fd)
    return fd


#变为灰度图片
def rgb2gray(im):
    gray = im[:, :, 0]*0.2989+im[:, :, 1]*0.5870+im[:, :, 2]*0.1140
    return gray

if __name__ == '__main__':
    get_feat()

第四步,进行图片检索

创建第四个文件,命名为search.py。

#coding:utf-8
import searcher
import cv2
import getfeat


queryFeatures = getfeat.get_feat()
#print(queryFeatures)
results = searcher.search(queryFeatures)

#显示查询图像
image = 'beach_001.jpg'
Query = cv2.imread(image)
cv2.imshow('Query',Query)

for (score, resultID) in results:
    #加载结果图像并显示它
    result = cv2.imread("image" + "/" + resultID)
    cv2.imshow("Result", result)
    cv2.waitKey(0)
    print(score)
    print(resultID)

结果

使用HOG+卡方距离的方法实现图片检索(python写)_第1张图片

由于图片的数量较少,所以结果只返回了5张。后续将添加数据集进行重新实验,并且调整相关的参数看能否提高检索的精度。

如有什么问题或者需要数据集,可与小编进行联系,邮箱:[email protected]

你可能感兴趣的:(python,HOG+卡方,图片检索)