OpenCV进行图像相似度对比的几种办法
生活随笔
收集整理的這篇文章主要介紹了
OpenCV进行图像相似度对比的几种办法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
平均哈希算法
實現步驟
代碼
int aHash(Mat matSrc1, Mat matSrc2) {Mat matDst1, matDst2;cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);int iAvg1 = 0, iAvg2 = 0;int arr1[64], arr2[64];for (int i = 0; i < 8; i++){uchar* data1 = matDst1.ptr<uchar>(i);uchar* data2 = matDst2.ptr<uchar>(i);int tmp = i * 8;for (int j = 0; j < 8; j++){int tmp1 = tmp + j;arr1[tmp1] = data1[j] / 4 * 4;arr2[tmp1] = data2[j] / 4 * 4;iAvg1 += arr1[tmp1];iAvg2 += arr2[tmp1];}}iAvg1 /= 64;iAvg2 /= 64;for (int i = 0; i < 64; i++){arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;}int iDiffNum = 0;for (int i = 0; i < 64; i++)if (arr1[i] != arr2[i])++iDiffNum;return iDiffNum; }感知哈希算法
平均哈希算法過于嚴格,不夠精確,更適合搜索縮略圖,為了獲得更精確的結果可以選擇感知哈希算法,它采用的是DCT(離散余弦變換)來降低頻率的方法
一般步驟
代碼
int pHash(Mat matSrc1, Mat matSrc2) {Mat matDst1, matDst2;cv::resize(matSrc1, matDst1, cv::Size(32, 32), 0, 0, cv::INTER_CUBIC);cv::resize(matSrc2, matDst2, cv::Size(32, 32), 0, 0, cv::INTER_CUBIC);cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);matDst1.convertTo(matDst1, CV_32F);matDst2.convertTo(matDst2, CV_32F);dct(matDst1, matDst1);dct(matDst2, matDst2);int iAvg1 = 0, iAvg2 = 0;int arr1[64], arr2[64];for (int i = 0; i < 8; i++){uchar* data1 = matDst1.ptr<uchar>(i);uchar* data2 = matDst2.ptr<uchar>(i);int tmp = i * 8;for (int j = 0; j < 8; j++){int tmp1 = tmp + j;arr1[tmp1] = data1[j];arr2[tmp1] = data2[j];iAvg1 += arr1[tmp1];iAvg2 += arr2[tmp1];}}iAvg1 /= 64;iAvg2 /= 64;for (int i = 0; i < 64; i++){arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;}int iDiffNum = 0;for (int i = 0; i < 64; i++)if (arr1[i] != arr2[i])++iDiffNum;return iDiffNum; }dHash算法
平均結構相似性 MSSIM 算法
原理
代碼
double getMSSIM(const Mat& i1, const Mat& i2) {const double C1 = 6.5025, C2 = 58.5225;/***************************** INITS **********************************/int d = CV_32F;Mat I1, I2;i1.convertTo(I1, d); // cannot calculate on one byte large valuesi2.convertTo(I2, d);Mat I2_2 = I2.mul(I2); // I2^2Mat I1_2 = I1.mul(I1); // I1^2Mat I1_I2 = I1.mul(I2); // I1 * I2/*************************** END INITS **********************************/Mat mu1, mu2; // PRELIMINARY COMPUTINGGaussianBlur(I1, mu1, Size(11, 11), 1.5);GaussianBlur(I2, mu2, Size(11, 11), 1.5);Mat mu1_2 = mu1.mul(mu1);Mat mu2_2 = mu2.mul(mu2);Mat mu1_mu2 = mu1.mul(mu2);Mat sigma1_2, sigma2_2, sigma12;GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);sigma1_2 -= mu1_2;GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);sigma2_2 -= mu2_2;GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);sigma12 -= mu1_mu2;/ FORMULA Mat t1, t2, t3;t1 = 2 * mu1_mu2 + C1;t2 = 2 * sigma12 + C2;t3 = t1.mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))t1 = mu1_2 + mu2_2 + C1;t2 = sigma1_2 + sigma2_2 + C2;t1 = t1.mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))Mat ssim_map;divide(t3, t1, ssim_map); // ssim_map = t3./t1;Scalar mssim = mean(ssim_map); // mssim = average of ssim mapreturn (mssim[0] + mssim[1] + mssim[2])/3; }由于項目需要使用了上述算法,測試后發現平均哈希算法進行兩張圖像相似度對比的效果是最好的(有些奇怪)。測試的樣本大多是完全相同的兩個圖片(只是明暗度不一樣,比如陰影),iDiffNum 的值一般在10左右。對于明顯不同的兩張圖片,上述算法都存在錯誤判斷的情況(返回的iDiffNum在10左右,正常的應該在20以外)。
reference:
[1] http://blog.csdn.net/wangyaninglm/article/details/43853435
[2] http://www.jb51.net/article/83315.htm
[3] http://blog.csdn.net/ecnu18918079120/article/details/60149864
總結
以上是生活随笔為你收集整理的OpenCV进行图像相似度对比的几种办法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决:Field xxMapper in
- 下一篇: 解决:which: no java in