C#結合OpenCVSharp4實現(xiàn)圖片相似度識別
OpenCVSharp4圖片相似度識別
需求背景:需要計算兩個圖片的相似度,然后將相似的圖片進行歸納
1. 圖片相似度算法
由于我是CRUD后端仔,對圖像處理沒什么概念。因此網(wǎng)上調研了幾種相似度算法分析其適用場景。
直方圖算法
獲取要比較的2個圖片的直方圖數(shù)據(jù),然后再將直方圖數(shù)據(jù)歸一化比較,最終得到一個相似指數(shù),通過設定相似指數(shù)的邊界,以此判斷是否相同圖片。
平均值哈希算法 aHash
轉灰度壓縮之后計算均值,最終通過像素比較得出哈希值,速度很快,但敏感度很高,稍有變化就會極大影響判定結果,精準度較差。因此比較適用于縮略圖比較,最常用的就是以圖搜圖
感知哈希算法 pHash
在均值哈希基礎上加入DCT
(離散余弦變化),兩次DCT
就可以很好的將圖像按照頻度分開,取左上角高能低頻信息做均值哈希,因此,精確度很高,但是速度方面較差一些。相比較aHash
,pHash
更加適合用于縮略圖比較,也非常適合比較兩個近似圖片是否相等。
差異值哈希算法 dHash
灰度壓縮之后,比較相鄰像素之間差異。假設有10×10的圖像,每行10個像素,就會產(chǎn)生9個差異值,一共10行,就一共有9×10=90個差異值。最終生成哈希值即指紋。速度上來說,介于aHash
和pHash
之間,精準度同樣也介于aHash
和pHash
之間。
結構相似性算法 SSIM
SSIM(structural similarity)
,結構相似性,是一種衡量兩幅圖像相似度的指標。SSIM
算法主要用于檢測兩張相同尺寸的圖像的相似度、或者檢測圖像的失真程度。原論文中,SSIM
算法主要通過分別比較兩個圖像的亮度,對比度,結構,然后對這三個要素加權并用乘積表示。
SSIM
算法在設計上考慮了人眼的視覺特性,它能夠考慮到圖像的結構信息在人的感知上的模糊變化,該模型還引入了一些與感知上的變化有關的感知現(xiàn)象,包含亮度mask和對比mask,結構信息指的是像素之間有著內部的依賴性,尤其是空間上靠近的像素點。這些依賴性攜帶著目標對象視覺感知上的重要信息。
經(jīng)過調研對比,這里就選擇SSIM
算法。
2. 下載OpenCVSharp4
通過NuGet包管理器進行下載。搜索OpenCVSharp4
下載。
請注意其描述信息:OpenCV wrapper for .NET. Since this package includes only core managed libraries, another package of native bindings for your OS is required (OpenCvSharp4.runtime.*).
這是說:OpenCV 包只是一個核心庫,如需在你的系統(tǒng)上使用,還需要對應的運行時包,這里是Windows系統(tǒng),因此還需下載 OpenCvSharp4.runtime.win
3. 使用
在項目中引入OpenCvSharp
using OpenCvSharp;
由于OpenCVSharp4
沒有直接提供封裝SSIM
算法的接口,因此需要自行寫這部分代碼。完整代碼如下
public Scalar Compare_SSIM(string imgFile1, string imgFile2) { var image1 = Cv2.ImRead(imgFile1); var image2Tmp = Cv2.ImRead(imgFile2); // 將兩個圖片處理成同樣大小,否則會有錯誤: The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' var image2 = new Mat(); Cv2.Resize(image2Tmp, image2, new OpenCvSharp.Size(image1.Size().Width, image1.Size().Height)); double C1 = 6.5025, C2 = 58.5225; var validImage1 = new Mat(); var validImage2 = new Mat(); image1.ConvertTo(validImage1, MatType.CV_32F); //數(shù)據(jù)類型轉換為 float,防止后續(xù)計算出現(xiàn)錯誤 image2.ConvertTo(validImage2, MatType.CV_32F); Mat image1_1 = validImage1.Mul(validImage1); //圖像乘積 Mat image2_2 = validImage2.Mul(validImage2); Mat image1_2 = validImage1.Mul(validImage2); Mat gausBlur1 = new Mat(), gausBlur2 = new Mat(), gausBlur12 = new Mat(); Cv2.GaussianBlur(validImage1, gausBlur1, new OpenCvSharp.Size(11, 11), 1.5); //高斯卷積核計算圖像均值 Cv2.GaussianBlur(validImage2, gausBlur2, new OpenCvSharp.Size(11, 11), 1.5); Cv2.GaussianBlur(image1_2, gausBlur12, new OpenCvSharp.Size(11, 11), 1.5); Mat imageAvgProduct = gausBlur1.Mul(gausBlur2); //均值乘積 Mat u1Squre = gausBlur1.Mul(gausBlur1); //各自均值的平方 Mat u2Squre = gausBlur2.Mul(gausBlur2); Mat imageConvariance = new Mat(), imageVariance1 = new Mat(), imageVariance2 = new Mat(); Mat squreAvg1 = new Mat(), squreAvg2 = new Mat(); Cv2.GaussianBlur(image1_1, squreAvg1, new OpenCvSharp.Size(11, 11), 1.5); //圖像平方的均值 Cv2.GaussianBlur(image2_2, squreAvg2, new OpenCvSharp.Size(11, 11), 1.5); imageConvariance = gausBlur12 - gausBlur1.Mul(gausBlur2);// 計算協(xié)方差 imageVariance1 = squreAvg1 - gausBlur1.Mul(gausBlur1); //計算方差 imageVariance2 = squreAvg2 - gausBlur2.Mul(gausBlur2); var member = ((2 * gausBlur1.Mul(gausBlur2) + C1).Mul(2 * imageConvariance + C2)); var denominator = ((u1Squre + u2Squre + C1).Mul(imageVariance1 + imageVariance2 + C2)); Mat ssim = new Mat(); Cv2.Divide(member, denominator, ssim); var sclar = Cv2.Mean(ssim); return sclar; // 變化率,即差異 }
實際檢測效果如下
這兩幅圖的相似度大約是92.21%,基本符合預期
這兩幅圖居然還有約18%的相似度,根據(jù)SSIM
算法特性,這應該是圖片大小的相似。
以上就是C#結合OpenCVSharp4實現(xiàn)圖片相似度識別的詳細內容,更多關于C# OpenCVSharp4的資料請關注腳本之家其它相關文章!
相關文章
c#操作sqlserver數(shù)據(jù)庫的簡單示例
這篇文章主要介紹了c#操作sqlserver數(shù)據(jù)庫的簡單示例,需要的朋友可以參考下2014-04-04C# WinForm控件對透明圖片重疊時出現(xiàn)圖片不透明的簡單解決方法
這篇文章主要介紹了C# WinForm控件對透明圖片重疊時出現(xiàn)圖片不透明的簡單解決方法,結合實例形式分析了WinForm圖片重疊后造成圖片不透明的原因與相應的解決方法,需要的朋友可以參考下2016-06-06