比较两幅图像的相似度
現(xiàn)在以圖搜圖的功能比較火熱,很好奇其原理。
簡單的搜索學習得知,實現(xiàn)相似圖片搜索的關鍵技術是“感知哈希算法”,作用是對每一張圖片按照某種規(guī)律生成一個對應的指紋字符串。比較不同圖片之間的指紋字符串,結果越接近,圖片越相似。
現(xiàn)將問題簡化為研究兩幅圖像的相似度,算法可能其他博客都有介紹了,現(xiàn)給出實現(xiàn)代碼(簡易版)。簡易版指紋字符串的算法思想如下:
1.輸入圖像
2.灰度化
3.將圖像大小歸一化到8*8尺寸
4.簡化灰度以減少計算量,例如所有的灰度除以5
5.計算平均灰度值avg
6.比較8*8=64個像素與平均灰度值avg的大小,若大則記為1,小則記為0,按一定順序排列成64位2進制的指紋編碼。
7.比較兩幅圖像的指紋編碼,計算相似度。
測試樣例:(依次為example1,example2,example3,example4)
測試結果:
example1-example2 :?64.0625%,not similar.
example1-example3 :?71.875%,a little?similar.
example1-example4 :?95.3125%,extremely similar.
?
代碼如下,只有一個文件哦(main.cpp):
?
#include <opencv2/opencv.hpp>
using namespace std;
string ImageHashValue(IplImage* src); ?//計算圖片的指紋信息
double ImageSimilarity(string &str1,string &str2); ?//根據(jù)指紋信息計算兩幅圖像的相似度
int main()
{
IplImage* image1 = cvLoadImage("example1.jpg",1);
IplImage* image2 = cvLoadImage("example3.jpg",1);
cvShowImage("image1",image1);
cvShowImage("image2",image2);
string imgPrint1 = ImageHashValue(image1);
string imgPrint2 = ImageHashValue(image2);
double similarity = ImageSimilarity(imgPrint1,imgPrint2);
cout<<"The similarity of two images is "<<similarity*100<<"%"<<endl;
if(similarity>=0.9)
cout<<"The two images are extremely similar."<<endl;
else if(similarity>=0.8&&similarity<0.9)
cout<<"The two images are pretty similar."<<endl;
else if(similarity>=0.7&&similarity<0.8)
cout<<"The two images are a little similar."<<endl;
else if(similarity<0.7)
cout<<"The two image are not similar."<<endl;
cout<<endl;
cvWaitKey(0);
}
//計算圖片的指紋信息
string ImageHashValue(IplImage* src)
{
string resStr(64,'\0');
IplImage* image = ?cvCreateImage(cvGetSize(src),src->depth,1);
//step one : 灰度化
if(src->nChannels == 3) ?cvCvtColor(src,image,CV_BGR2GRAY);
else ?cvCopy(src,image);
//step two : 縮小尺寸 8*8
IplImage* temp = cvCreateImage(cvSize(8,8),image->depth,1);
cvResize(image,temp);
//step three : 簡化色彩
uchar* pData;
for(int i=0; i<temp->height; i++)
{
pData =(uchar* )(temp->imageData+i*temp->widthStep);
for(int j=0; j<temp->width;j++)
pData[j]= pData[j]/4;
}
//step four : 計算平均灰度值
int average = cvAvg(temp).val[0];
//step five : 計算哈希值
int index = 0;
for(int i=0; i<temp->height; i++)
{
pData =(uchar* )(temp->imageData+i*temp->widthStep);
for(int j=0; j<temp->width;j++)
{
if(pData[j]>=average)
resStr[index++]='1';
else?
resStr[index++]='0';
}
}
return resStr;
}
//根據(jù)指紋信息計算兩幅圖像的相似度
double ImageSimilarity(string &str1,string &str2)
{
double similarity = 1.0;
for(int i=0;i<64;i++)
{
char c1 = str1[i];
char c2 = str2[i];
if(c1!=c2)
similarity = similarity -1.0/64;
}
return similarity;
}
轉自https://blog.csdn.net/zhuason/article/details/78933250
總結
以上是生活随笔為你收集整理的比较两幅图像的相似度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python+Opencv识别两张相似图
- 下一篇: 解决:Field xxMapper in