r语言把两个折线图图像放到一个图里_图像相似度度量
圖像相似度度量的應用場景很多,包括以圖搜圖,相似圖像去重等多種功能,目前在項目中的場景是針對大量重復類似的圖片,需要進行篩選剔除,自然需要用到圖像相似度,簡單調研了下圖像相似度的方法,包括傳統圖像方法和機遇深度學習的方法。
有個很 naive 的搞法是拿隨便一個什么 imagenet 網絡的倒數第二層結果做 feature vector。但是因為這是基于分類的結果,必然是丟棄紋理而取高層語義的。那么如果你的需求就是比較一堆比方說大理石紋理……我猜這個 feature 都未必比得上直接比直方圖。
還有比如使用AM-softmax進行分類訓練,把訓練好的網絡去掉最后一層分類層,選取最后一個隱藏層輸出作為一個數據的特征。兩個數據特征使用余弦相似度進行計算,簡單來說,拿一個在imagenet上預訓練的vgg模型提取圖像特征,然后用余弦比較兩個特征向量的相似度。
傳統圖像方法,主要是哈希算法,分別有以下幾種:
平均哈希算法(ahash):
此算法是基于比較灰度圖每個像素與平均值來實現的,最適用于縮略圖,放大圖搜索。
1.縮放圖片:為了保留結構去掉細節,去除大小、橫縱比的差異,把圖片統一縮放到8*8,共64個像素的圖片。
2.轉化為灰度圖:把縮放后的圖片轉化為256階的灰度圖。
附上灰度圖相關算法(R = red, G = green, B = blue)
1.浮點算法:Gray=R*0.3+G*0.59+B*0.11
2.整數方法:Gray=(R*30+G*59+B*11)/100
3.移位方法:Gray =(R*76+G*151+B*28)>>8;
4.平均值法:Gray=(R+G+B)/3;
5.僅取綠色:Gray=G;
3.計算平均值: 計算進行灰度處理后圖片的所有像素點的平均值。
4.比較像素灰度值:遍歷灰度圖片每一個像素,如果大于平均值記錄為1,否則為0.
5.得到信息指紋:組合64個bit位,順序隨意保持一致性即可。
6.對比指紋:計算兩幅圖片的指紋,計算漢明距離(從一個指紋到另一個指紋需要變幾次),漢明距離越大則說明圖片越不一致,反之,漢明距離越小則說明圖片越相似,當距離為0時,說明完全相同。(通常認為距離>10 就是兩張完全不同的圖片)
感知哈希算法(phash):
平均哈希算法過于嚴格,不夠精確,更適合搜索縮略圖,為了獲得更精確的結果可以選擇感知哈希算法,它采用的是DCT(離散余弦變換)來降低頻率的方法
1.縮小圖片:32 * 32是一個較好的大小,這樣方便DCT計算
2.轉化為灰度圖:把縮放后的圖片轉化為256階的灰度圖。(具體算法見平均哈希算法步驟)
3.計算DCT:DCT把圖片分離成分率的集合
4.縮小DCT:DCT是32*32,保留左上角的8*8,這些代表的圖片的最低頻率
5.計算平均值:計算縮小DCT后的所有像素點的平均值。
6.進一步減小DCT:大于平均值記錄為1,反之記錄為0.
7.得到信息指紋:組合64個信息位,順序隨意保持一致性即可
8.對比指紋:計算兩幅圖片的指紋,計算漢明距離(從一個指紋到另一個指紋需要變幾次),漢明距離越大則說明圖片越不一致,反之,漢明距離越小則說明圖片越相似,當距離為0時,說明完全相同。(通常認為距離>10 就是兩張完全不同的圖片)
感知哈希算法示例代碼:
#!/usr/bin/env python # -*- encoding: utf-8 -*- ''' @File :sample_diff.py @Date :2020/03/31 10:18:00 @Author :mrwang @Version :1.0 '''from PIL import Image from os import listdirdef picPostfix(): # 圖片后綴的集合postFix = set()postFix.update(['bmp', 'jpg', 'png', 'tiff', 'gif', 'pcx', 'tga', 'exif','fpx', 'svg', 'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'JPG', 'raw', 'jpeg'])return postFixdef getDiff(width, height, image): # 將要裁剪成w*h的image照片 得到漸變序列diff = []im = image.resize((width, height))imgray = im.convert('L') # 轉換為灰度圖片 便于處理pixels = list(imgray.getdata()) # 得到像素數據 灰度0-255for row in range(height):rowStart = row * width # 起始位置行號for index in range(width - 1):leftIndex = rowStart + index # 當前位置號rightIndex = leftIndex + 1diff.append(pixels[leftIndex] > pixels[rightIndex])return diffdef getHamming(diff=[], diff2=[]):# print len(diff)hamming_distance = 0for i in range(len(diff)):if diff[i] != diff2[i]:hamming_distance += 1return hamming_distanceif __name__ == '__main__':width = 32height = 32thre = 100 #判別的漢明距離閾值,根據自己情況設置dirName = "/home/workspace/lost/Images" # 圖片路徑allDiff = []postFix = picPostfix()dirList = listdir(dirName)cnt = 0for i in dirList:cnt += 1print('cnt:', cnt)if str(i).split('.')[-1] in postFix: # 判斷后綴是不是照片格式im = Image.open(r'%s/%s' % (dirName, str(i)))diff = getDiff(width, height, im)allDiff.append((str(i), diff))print(len(allDiff))for i in range(len(allDiff)):for j in range(i + 1, len(allDiff)):if i != j:ans = getHamming(allDiff[i][1], allDiff[j][1])if ans <= thre:print(allDiff[i][0], "and", allDiff[j][0], "maybe same photo.")差異哈希算法(dhash):
相比pHash,dHash的速度要快的多,相比aHash,dHash在效率幾乎相同的情況下的效果要更好,它是基于漸變實現的。
1.縮小圖片:收縮到9*8的大小,一遍它有72的像素點
2.轉化為灰度圖:把縮放后的圖片轉化為256階的灰度圖。(具體算法見平均哈希算法步驟)
3.計算差異值:dHash算法工作在相鄰像素之間,這樣每行9個像素之間產生了8個不同的差異,一共8行,則產生了64個差異值
4.獲得指紋:如果左邊的像素比右邊的更亮,則記錄為1,否則為0.
需要說明的是這種指紋算法不僅可以應用于圖片搜索,同樣適用于其他多媒體形式。除此之外,圖片搜索特征提取方法有很多,很多算法還有許多可以改進的地方,比如對于人物可以先進行人臉識別,再在面部區域進行局部的哈希,或者背景是純色的可以先過濾剪裁等等。
深度學習的方法,主要是孿生網絡:
Siamese networks(孿生網絡)
首先我們會喂給神經網絡成對的圖片,然后訓練網絡讓它去猜測這兩個圖片是否屬于同一類別。然后在給定測試集的樣本時,神經網絡可以將該樣本與測試集中的樣本配對并且選擇出最有可能和測試集同類別的樣本,因此我們需要的神經網絡模型的輸入是兩張圖片,然后輸出它們之間屬于同一類別的可能性。
假設
是數據集中的兩個樣本,屬于同一個類別記為 ,很明顯和 等價。這也就說明在給神經網絡喂數據時,即使兩張照片調換順序最后的輸出也不會受到影響。這種特性被稱為“對稱性”。這樣的特性就決定了我們需要學習一種距離度量,即從 到 的距離等價于從 到 的距離。如果我們將兩個樣本連接(concate操作)在一起形成單個輸入并且將其喂給神經網絡,那么每個合成樣本(調換兩個樣本concate的順序,整個合成矩陣的結構就不一樣了)的矩陣元素會和不同的一系列權重值相稱或卷積,這就打破了“對稱性”的原則。換句話說,即使是對不同順序的輸入最后都能學習到相同的weights參數,因此我們可以設計一種相同的網絡結構并且兩者之間權重共享,每種網絡結構對應于一個input(因為兩者完全相同,因此兩個input即使調換位置也不會影響模型的學習)。然后用絕對值距離作為輸入喂給線性分類器得到output。這就是Siamese network 的由來。
基于孿生網絡的方法有個短板就是訓練數據要有label。cvpr2016年有一篇論文是基于無監督的,Learning Compact Binary Descriptors with Unsupervised Deep Neural Networks cvpr,重點是無監督,圖像可以是無label的,實際上是大量的樣本自己去產生類似的hash值,隱含的聚類。
總結
以上是生活随笔為你收集整理的r语言把两个折线图图像放到一个图里_图像相似度度量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pwm波如何控制电机代码_柴油发电机机组
- 下一篇: access设计视图打不开_定制橱柜衣柜