1. 程式人生 > >使用HOG+卡方距離的方法實現圖片檢索(python寫)

使用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)

結果

這裡寫圖片描述

由於圖片的數量較少,所以結果只返回了5張。後續將新增資料集進行重新實驗,並且調整相關的引數看能否提高檢索的精度。

如有什麼問題或者需要資料集,可與小編進行聯絡,郵箱:[email protected]