題目:根據提供的資料實作一個圖片檢索類,輸入一張圖片,展示資料庫中最相似的前 n 張照片,
資料資源: 約 4000 張人臉
要點:如何計算圖片的相似性;如何實作快速的比對,
注意:圖片資料應該只匯入記憶體一次,避免每次檢索 都要重新匯入圖片;實作統計一次檢索耗費時間的裝飾器;檢索應有閾值要求(如相似性大于某值時定義為不相似),當在對應閾值下無檢索結果時拋出自定義例外并在上層呼叫時處理;
一、 代碼思路
- 匯入圖片路徑,存盤為一個
list - 計算圖片的哈希值, 建立字典,存盤每張圖片的路徑及對應的哈希值
- 在主函式中建立
while回圈,輸入圖片路徑時開始檢索,若輸入的圖片路徑不正確,則輸出“圖片不存在”,輸入q時,退出程式,While回圈可以使圖片資料只匯入記憶體一次,避免每次檢索都要重新匯入圖片 - 實作統計一次檢索耗費時間的裝飾器,當兩張圖片的哈希值的差值小于 20 時,定義為相似 ,將相似圖片存盤在佇列中,最后畫圖,當在對應閾值下的相似照片不足 9 張值,拋出自定義例外,
二、 代碼實作
- 匯入圖片路徑,存盤為一個
list
import sys
import os
import numpy as np
from heapq import heappush
from heapq import heappop
import matplotlib.pyplot as plt
from PIL import Image
import imagehash
import time
import line_profiler
#load images
def load_images():
imflist=[]
fpath = r'icon'
for root,dirs,files in os.walk(fpath):
for file in files:
if file.find('.ppm')>0:
print(os.path.join(root,file))
imflist.append(os.path.join(root,file))
return imflist
- 計算圖片的哈希值,建立字典,存盤每張圖片的路徑及對應的哈希值
def hash_image(flist):
im_hash_map={}
for file in flist:
im = Image.open(file)
im_a_hash = imagehash.average_hash(im)
im_hash_map[file] = im_a_hash
return im_hash_map
- 實作裝飾期和圖片檢索
實作統計一次檢索耗費時間的裝飾器@profile:安裝line_profiler,安裝完成后,將有一個“line_profiler”的新模組和一個”kernprof.py”可執行腳本,在想測量執行時間的函式上裝飾@profile裝飾器,在命令列中輸入kernprof.py -l -v func_name,kernprof.py腳本將會在執行的時自動地注入到你的腳本的運行,
-l, --line-by-line Use the line-by-line profiler from the line_profiler module instead of Profile. Implies --builtin.
-v, --view View the results of the profile in addition to saving it.
當兩張圖片的哈希值的差值小于20 時,定義為相似,將相似圖片存盤在佇列中,最后畫圖,當在對應閾值下的相似照片不足 9 張值,拋出自定義例外,
@profile
def simi_image(im_hash_map, im):
simi_images=[]
if im in im_hash_map.keys():
for image in im_hash_map:
simi=im_hash_map[image]-im_hash_map[im]
# 哈希值差值小于20時,定義為相似
if simi < 15:
heappush(simi_images,(simi,image))
plt.figure()
plt.subplot(4,3,2)
im=Image.open(im)
plt.imshow(im)
plt.axis('off')
for i in range(4,13):
try:
image=heappop(simi_images)
im=Image.open(image[1])
plt.subplot(4,3,i)
plt.imshow(im)
plt.axis('off')
except:
plt.show()
print("no more similar photos")
plt.show()
else:
print('圖片不存在')
- 主函式
def main():
imflist = load_images()
im_hash_map = hash_image(imflist)
im = 1
while im != 'q':
im = input('輸入q退出,或輸入圖片路徑:')
if im != 'q':
simi_image(im_hash_map, im)
else:
break
if __name__ == '__main__':
main()



當閾值為15 時,只有 5 張圖片滿足相似, 計算哈希值差異的陳述句花費了 121422個時間單位,該函式共運行了 9.2934 秒
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297668.html
標籤:其他
上一篇:OpenCV-影像對比度
