一、待搜索圖
二、測試集
三、new_similarity_compare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# -*- encoding=utf-8 -*- from image_similarity_function import * import os import shutil # 融合相似度閾值 threshold1 = 0.70 # 最終相似度較高判斷閾值 threshold2 = 0.95 # 融合函數計算圖片相似度 def calc_image_similarity(img1_path, img2_path): """ :param img1_path: filepath+filename :param img2_path: filepath+filename :return: 圖片最終相似度 """ similary_ORB = float (ORB_img_similarity(img1_path, img2_path)) similary_phash = float (phash_img_similarity(img1_path, img2_path)) similary_hist = float (calc_similar_by_path(img1_path, img2_path)) # 如果三種算法的相似度最大的那個大于0.7,則相似度取最大,否則,取最小。 max_three_similarity = max (similary_ORB, similary_phash, similary_hist) min_three_similarity = min (similary_ORB, similary_phash, similary_hist) if max_three_similarity > threshold1: result = max_three_similarity else : result = min_three_similarity return round (result, 3 ) if __name__ = = '__main__' : # 搜索文件夾 filepath = r 'D:\Dataset\cityscapes\leftImg8bit\val\frankfurt' #待查找文件夾 searchpath = r 'C:\Users\Administrator\Desktop\cityscapes_paper' # 相似圖片存放路徑 newfilepath = r 'C:\Users\Administrator\Desktop\result' for parent, dirnames, filenames in os.walk(searchpath): for srcfilename in filenames: img1_path = searchpath + "\\" + srcfilename for parent, dirnames, filenames in os.walk(filepath): for i, filename in enumerate (filenames): print ( "{}/{}: {} , {} " . format (i + 1 , len (filenames), srcfilename,filename)) img2_path = filepath + "\\" + filename # 比較 kk = calc_image_similarity(img1_path, img2_path) try : if kk > = threshold2: # 將兩張照片同時拷貝到指定目錄 shutil.copy(img2_path, os.path.join(newfilepath, srcfilename[: - 4 ] + "_" + filename)) except Exception as e: # print(e) pass |
四、image_similarity_function.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# -*- encoding=utf-8 -*- # 導入包 import cv2 from functools import reduce from PIL import Image # 計算兩個圖片相似度函數ORB算法 def ORB_img_similarity(img1_path, img2_path): """ :param img1_path: 圖片1路徑 :param img2_path: 圖片2路徑 :return: 圖片相似度 """ try : # 讀取圖片 img1 = cv2.imread(img1_path, cv2.IMREAD_GRAYSCALE) img2 = cv2.imread(img2_path, cv2.IMREAD_GRAYSCALE) # 初始化ORB檢測器 orb = cv2.ORB_create() kp1, des1 = orb.detectAndCompute(img1, None ) kp2, des2 = orb.detectAndCompute(img2, None ) # 提取并計算特征點 bf = cv2.BFMatcher(cv2.NORM_HAMMING) # knn篩選結果 matches = bf.knnMatch(des1, trainDescriptors = des2, k = 2 ) # 查看最大匹配點數目 good = [m for (m, n) in matches if m.distance < 0.75 * n.distance] similary = len (good) / len (matches) return similary except : return '0' # 計算圖片的局部哈希值--pHash def phash(img): """ :param img: 圖片 :return: 返回圖片的局部hash值 """ img = img.resize(( 8 , 8 ), Image.ANTIALIAS).convert( 'L' ) avg = reduce ( lambda x, y: x + y, img.getdata()) / 64. hash_value = reduce ( lambda x, y: x | (y[ 1 ] << y[ 0 ]), enumerate ( map ( lambda i: 0 if i < avg else 1 , img.getdata())), 0 ) return hash_value # 計算兩個圖片相似度函數局部敏感哈希算法 def phash_img_similarity(img1_path, img2_path): """ :param img1_path: 圖片1路徑 :param img2_path: 圖片2路徑 :return: 圖片相似度 """ # 讀取圖片 img1 = Image. open (img1_path) img2 = Image. open (img2_path) # 計算漢明距離 distance = bin (phash(img1) ^ phash(img2)).count( '1' ) similary = 1 - distance / max ( len ( bin (phash(img1))), len ( bin (phash(img1)))) return similary # 直方圖計算圖片相似度算法 def make_regalur_image(img, size = ( 256 , 256 )): """我們有必要把所有的圖片都統一到特別的規格,在這里我選擇是的256x256的分辨率。""" return img.resize(size).convert( 'RGB' ) def hist_similar(lh, rh): assert len (lh) = = len (rh) return sum ( 1 - ( 0 if l = = r else float ( abs (l - r)) / max (l, r)) for l, r in zip (lh, rh)) / len (lh) def calc_similar(li, ri): return sum (hist_similar(l.histogram(), r.histogram()) for l, r in zip (split_image(li), split_image(ri))) / 16.0 def calc_similar_by_path(lf, rf): li, ri = make_regalur_image(Image. open (lf)), make_regalur_image(Image. open (rf)) return calc_similar(li, ri) def split_image(img, part_size = ( 64 , 64 )): w, h = img.size pw, ph = part_size assert w % pw = = h % ph = = 0 return [img.crop((i, j, i + pw, j + ph)).copy() for i in range ( 0 , w, pw) \ for j in range ( 0 , h, ph)] |
五、結果
到此這篇關于Python圖片檢索之以圖搜圖的文章就介紹到這了,更多相關Python以圖搜圖內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_43723625/article/details/117298412