我是靠谱客的博主 高大麦片,这篇文章主要介绍图片相似度计算,现在分享给大家,希望可以做个参考。

今天自己写了一个简单的计算图相似度的算法,借鉴了哈希算法思想进行编写,在此分享给大家!

总体思路 :

(借鉴了相似图像搜素的关键技术——哈希算法)将每一张图片人为转换具有0或1规律表达的图像,即将图像按照某个阈值生成对应的指纹字符串。我们最终是通过比较不同图片转后对应位置的指纹字符串,其结果越是趋向于1越相似。

主要实现的步骤如下:
Step 1. 输入图像
Step 2. 进行灰度化 (如果是需要更高精度的图像相似度计算,可以考虑利用原始图)
Step 3. 将输入的图像进行归一化到指定尺寸 例如9*9
Step 4. 等比降低灰度值 (grayValue/N 其中N是正整数,也可以省略)
Step 5. 计算图像平均灰度值average
Step 6. 生成指纹图,将归一化的图像每个位置Img(i,j)与平均灰度值average进行比较,若 Img(I,j)> average,则Img(i,j)=1,否则Img(I,j)=0;
Step 7. 按照一定排列顺序进行两幅图像比较,获得相似度similarity
我设定初始值similarity = 1。


接下来直接上代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//第一个函数:计算图片的指纹信息 string CalImgHashValue(IplImage* src) { int N = 5; //简化常数,人为设定 int graySum; string resStr(81,''); uchar* pData; IplImage* image = cvCreateImage(cvGetSize(src),src->depth,1); //step2 : 灰度化 if(src->nChannels == 3) cvCvtColor(src,image,CV_BGR2GRAY); else cvCopy(src,image); //step 3 : 缩小尺寸 9*9 IplImage* temp = cvCreateImage(cvSize(9,9),image->depth,1); cvResize(image,temp); //step 4 : 简化计算量 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]/N; } //step 5 : 计算平均灰度值 int count = 0; for (int row = 0; row< src->iHeight; row++) { for (int col = 0; col<= src->iWidth; col++) { graySum = graySum + (uchar)ImgGray->imageData[row*src->widthStep + col]; count++; } } int average = graySum/count; //step 6 : 计算哈希值 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; }

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
//第二个函数:计算两幅图像的相似度 void GetImgSimilarity(string &str1,string &str2,double* similarity) { *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; } }

复制代码
1
2
3
4
//声明 string CalImgHashValue(IplImage* src); //计算图片的指纹信息 void GetImgSimilarity(string &str1,string &str2); //根据指纹信息计算两幅图像的相似度

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//测试程序 #include <opencv2/opencv.hpp> using namespace std; int main() { IplImage* img1 = cvLoadImage("hanshanbuleng1.jpg",1); IplImage* img2 = cvLoadImage("hanshanbuleng2.jpg",1); cvShowImage("img1 ",img1 ); cvShowImage("img2 ",img2 ); string imgPrint1 = ImageHashValue(image1); string imgPrint2 = ImageHashValue(image2); double similarity = 0; ImageSimilarity(imgPrint1,imgPrint2,&similarity); cout<<"The similarity of two img is "<<similarity*100<<"%"<<endl; if(similarity>=0.9) cout<<"The two img are extremely similar."<<endl; else if(similarity>=0.8&&similarity<0.9) cout<<"The two imag are pretty similar."<<endl; else if(similarity>=0.7&&similarity<0.8) cout<<"The two imag are a little similar."<<endl; else if(similarity<0.7) cout<<"The two img are not similar."<<endl; cout<<endl; cvWaitKey(0); }

最后

以上就是高大麦片最近收集整理的关于图片相似度计算的全部内容,更多相关图片相似度计算内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部