首页 新闻 会员 周边

图片相似度计算:谁可以用代码帮我实现一个功能,我已经实现了部分简单的,后面的知识面不够,写不下去了

0
[已关闭问题] 关闭于 2012-04-28 09:58

原理如下:

根据Neal Krawetz博士的解释,原理非常简单易懂。我们可以用一个快速算法,就达到基本的效果。这里的关键技术叫做“感知哈希算法”(Perceptual hash algorithm),它的作用是对每张图片生成一个“指纹”(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似。

下面是一个最简单的实现:

第一步,缩小尺寸。将图片缩小到8×8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。

第二步,简化色彩。将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。

第三步,计算平均值。计算所有64个像素的灰度平均值。

第四步,比较像素的灰度。将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为。

第五步,计算哈希值。将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算“汉明距离”。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。

 

我的代码 只实现了到 第二步:

 1     class LikeImage
2 {
3 public void Compare(Image i1 ,Image i2)
4 {
5 Image i8x8 = get8x8Image(i1);
6 Image igray = getGrayImage(i8x8);
7 i8x8.Save("8.jpg");
8 igray.Dispose();
9 i8x8.Dispose();
10 }
11
12 ///<summary>
13 /// 图片灰度处理
14 ///</summary>
15 ///<param name="i"></param>
16 ///<returns></returns>
17 Image getGrayImage(Image i)
18 {
19 Bitmap bmPhoto = new Bitmap(i);
20 Graphics g = Graphics.FromImage(bmPhoto);
21
22 Color currentColor;
23 int r;
24 for (int w = 0; w < bmPhoto.Width; w++)
25 {
26 for (int h = 0; h < bmPhoto.Height; h++)
27 {
28 currentColor = bmPhoto.GetPixel(w, h);
29 r = (currentColor.R + currentColor.G + currentColor.B) / 3;
30
31 bmPhoto.SetPixel(w, h, Color.FromArgb(r, r, r));
32 }
33 }
34
35 g.Dispose();
36 return bmPhoto;
37 }
38
39 ///<summary>
40 /// 获得 8*8 的缩略图
41 ///</summary>
42 ///<param name="i"></param>
43 ///<returns></returns>
44 Image get8x8Image(Image i)
45 {
46 int size = 8;
47 int _x, _y,_size;
48
49 if (i.Height > i.Width)
50 {
51 _size = i.Width;
52 _x = 0;
53 _y = (int)Math.Round((double)(i.Height - _size) / 2, 0);
54 }
55 else
56 {
57 _size = i.Height;
58 _x = (int)Math.Round((double)(i.Width - _size) / 2, 0);
59 _y = 0;
60 }
61
62 Bitmap bmPhoto = new Bitmap(size, size, PixelFormat.Format24bppRgb);
63 bmPhoto.SetResolution(i.HorizontalResolution, i.VerticalResolution);
64 Graphics g = Graphics.FromImage(bmPhoto);
65 g.DrawImage(i,
66 new Rectangle(0, 0, size, size), ///它指定所绘制图像的位置和大小。
67 new Rectangle(_x, _y, _size, _size), ///它指定 image 对象中要绘制的部分。
68 GraphicsUnit.Pixel
69 );
70 g.Dispose();
71 return bmPhoto;
72 }
73 }



 

 

 

 

fun5的主页 fun5 | 初学一级 | 园豆:4
提问于:2012-01-02 21:59
< >
分享
所有回答(1)
0

你好,我实现过 一个灰度直方图匹配的算法~

最后是用一个算法公式:Sim(G,S)= 图像相似度算法的C#实现及测评

你的这个估计也差不多的,你扣扣多少我发给你看

吃栗子的猫 | 园豆:205 (菜鸟二级) | 2012-03-08 15:43

1500019596

支持(0) 反对(0) fun5 | 园豆:4 (初学一级) | 2012-03-13 13:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册