图像相似度计算之哈希值方法OpenCV实现
感知哈希算法(perceptual hash algorithm),它的作用是對每張圖像生成一個“指紋”(fingerprint)字符串,然后比較不同圖像的指紋。結果越接近,就說明圖像越相似。
實現步驟:
1.??????縮小尺寸:將圖像縮小到8*8的尺寸,總共64個像素。這一步的作用是去除圖像的細節,只保留結構/明暗等基本信息,摒棄不同尺寸/比例帶來的圖像差異;
2.??????簡化色彩:將縮小后的圖像,轉為64級灰度,即所有像素點總共只有64種顏色;
3.??????計算平均值:計算所有64個像素的灰度平均值;
4.??????比較像素的灰度:將每個像素的灰度,與平均值進行比較,大于或等于平均值記為1,小于平均值記為0;
5.??????計算哈希值:將上一步的比較結果,組合在一起,就構成了一個64位的整數,這就是這張圖像的指紋。組合的次序并不重要,只要保證所有圖像都采用同樣次序就行了;
6.??????得到指紋以后,就可以對比不同的圖像,看看64位中有多少位是不一樣的。在理論上,這等同于”漢明距離”(Hamming distance,在信息論中,兩個等長字符串之間的漢明距離是兩個字符串對應位置的不同字符的個數)。如果不相同的數據位數不超過5,就說明兩張圖像很相似;如果大于10,就說明這是兩張不同的圖像。
以上內容摘自:http://www.ruanyifeng.com/blog/2011/07/principle_of_similar_image_search.html
下面是用OpenCV實現的測試代碼:
string strSrcImageName = "src.jpg";cv::Mat matSrc, matSrc1, matSrc2;matSrc = cv::imread(strSrcImageName, CV_LOAD_IMAGE_COLOR);CV_Assert(matSrc.channels() == 3);cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST);//cv::flip(matSrc1, matSrc1, 1);cv::resize(matSrc, matSrc2, cv::Size(2177, 3233), 0, 0, cv::INTER_LANCZOS4);cv::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;cout<<"iDiffNum = "<<iDiffNum<<endl;if (iDiffNum <= 5)cout<<"two images are very similar!"<<endl;else if (iDiffNum > 10)cout<<"they are two different images!"<<endl;elsecout<<"two image are somewhat similar!"<<endl;
總結
以上是生活随笔為你收集整理的图像相似度计算之哈希值方法OpenCV实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: API Sanity Checker在U
- 下一篇: Git简介以及与SVN的区别