日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV进行图像相似度对比的几种办法

發布時間:2023/12/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV进行图像相似度对比的几种办法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

平均哈希算法

實現步驟

  • 縮小尺寸:將圖像縮小到8*8的尺寸,總共64個像素。這一步的作用是去除圖像的細節,只保留結構/明暗等基本信息,摒棄不同尺寸/比例帶來的圖像差異;
  • 簡化色彩:將縮小后的圖像,轉為64級灰度,即所有像素點總共只有64種顏色;
  • 計算平均值:計算所有64個像素的灰度平均值;
  • 比較像素的灰度:將每個像素的灰度,與平均值進行比較,大于或等于平均值記為1,小于平均值記為0;
  • 計算哈希值:將上一步的比較結果,組合在一起,就構成了一個64位的整數,這就是這張圖像的指紋。組合的次序并不重要,只要保證所有圖像都采用同樣次序就行了;
  • 得到指紋以后,就可以對比不同的圖像,看看64位中有多少位是不一樣的。在理論上,這等同于”漢明距離”(Hamming distance,在信息論中,兩個等長字符串之間的漢明距離是兩個字符串對應位置的不同字符的個數)。如果不相同的數據位數不超過5,就說明兩張圖像很相似;如果大于10,就說明這是兩張不同的圖像。
  • 代碼

    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(離散余弦變換)來降低頻率的方法

    一般步驟

  • 縮小圖片:32 * 32是一個較好的大小,這樣方便DCT計算
  • 轉化為灰度圖
  • 計算DCT:利用Opencv中提供的dct()方法,注意輸入的圖像必須是32位浮點型
  • 縮小DCT:DCT計算后的矩陣是32 * 32,保留左上角的8 * 8,這些代表的圖片的最低頻率
  • 計算平均值:計算縮小DCT后的所有像素點的平均值
  • 大于平均值記錄為1,反之記錄為0
  • 得到信息指紋
  • 代碼

    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算法

  • 縮小圖片:收縮到8*9的大小,以便它有72的像素點
  • 轉化為灰度圖
  • 計算差異值:dHash算法工作在相鄰像素之間,這樣每行9個像素之間產生了8個不同的差異,一共8行,則產生了64個差異值
  • 獲得指紋:如果左邊的像素比右邊的更亮,則記錄為1,否則為0
  • 平均結構相似性 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进行图像相似度对比的几种办法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。