既然选择远方,便只顾风雨兼程……

图像相似度算法的C#实现及测评

上一篇 / 下一篇  2009-04-28 11:57:41 / 个人分类:软件开发相关

51Testing软件测试网ZA,F3ST-h-p

  近日逛博客的时候偶然发现了一个有关图片相似度的Python算法实现。想着很有意思便搬到C#上来了,给大家看看。51Testing软件测试网C)XR$L.U h X P:t

闲言碎语51Testing软件测试网)R7h I*e/r9O+U!O

51Testing软件测试网M9kF"~wRi

  才疏学浅,只把计算图像相似度的一个基本算法的基本实现方式给罗列了出来,以至于在最后自己测评的时候也大发感慨,这个算法有点不靠谱。不管怎么样,这个算法有时候还是有用的,所以还是列出来跟大家伙一起分享分享~~

)^.a0aQYP4H2a!j]0

  PS:图像处理这一块博大精深,个人偶尔发现了点东西拿来分享。说的不好的地方,写得太糟的地方,诸位准备扔砖头还望淡定,淡定~~51Testing软件测试网Y0e+J^`H tj

51Testing软件测试网}X8o/K2\

基本知识介绍51Testing软件测试网$M u+F d/LN

颜色直方图

triArk0

               颜色直方图是在许多图像检索系统中被广泛采用的颜色特征,它所描述的是不同色彩在整幅图像中所占的比例,而并不关心每种色彩所处的空间位置,即无法描述图像中的对象或物体。颜色直方图特别适用于描述那些难以进行自动分割的图像。

$t W d&dd+?5aB#q F(o;D0

灰度直方图51Testing软件测试网*ng Cv8G0D

  灰度直方图是灰度级的函数,它表示图像中具有每种灰度级的像素的个数,反映图像中每种灰度出现的频率。灰度直方图的横坐标是灰度级,纵坐标是该灰度级出现的频率,是图像的最基本的统计特征。

:[Yn}x @U@0

   本文中即是使用灰度直方图来计算图片相似度,关于算法那一块也不赘言了,毕竟图像学图形学,直方图我是门儿都不懂,我也不准备打肿脸充胖子,只想实现一个最基本的算法,然后从最直观的角度看看这个算法的有效性,仅此而已。51Testing软件测试网u#N,IMC]&| @

 51Testing软件测试网(gS.g8vC2@#?7h

算法实现51Testing软件测试网*i$sUahgf b;H

               诸位看官休怪笔者囫囵吞枣,浅尝辄止的学习态度。额毕竟是因兴趣而来,于此方面并无半点基础(当然,除了知道RGB是啥玩意儿——这还幸亏当年计算机图形学的老师是个Super美女,因此多上了几节课的缘故),更谈不上半点造诣,看官莫怪莫怪,且忍住怒气,是走是留,小生不敢有半点阻拦~~

ZA%`*W2OU+e0

大致步骤如下:51Testing软件测试网 ?~{&@gW9g

1, 将图像转换成相同大小,以有利于计算出相像的直方图来

"p N] J xm9E` o)J0

2, 计算转化后的灰度直方图

I7O)J c q W%n6E i0

3, 利用XX公式,得到直方图相似度的定量度量51Testing软件测试网fGe-~p7Q

4, 输出这些不知道有用没用的相似度结果数据51Testing软件测试网4tR#~G\.c&d1^|

代码实现

b1hV]z;|frZ0

步骤1将图像转化成相同大小,我们暂且转化成256 X 256吧。51Testing软件测试网#W%qsFM

 51Testing软件测试网 P[-c-B0Hh

publicBitmapResize(stringimageFile,stringnewImageFile)

'l^?0nzOd0

       {51Testing软件测试网2F5].bx/MF"\

           img =Image.FromFile(imageFile);51Testing软件测试网bD/Twl&Jt"pw8y

           BitmapimgOutput =newBitmap(img, 256, 256);

h Ti$^A%v0

           imgOutput.Save(newImageFile, System.Drawing.Imaging.ImageFormat.Jpeg);51Testing软件测试网/pS7[7{8pK\ e"ZJ

           imgOutput.Dispose();51Testing软件测试网t W n)GXX*]M@8u

           return(Bitmap)Image.FromFile(newImageFile);

z~4JvqK"ot%zi`0

     }

hz)J!]3e'J0

 51Testing软件测试网h T{Xf7}

  这部分代码很好懂,imageFile为原始图片的完整路径,newImageFile为强转大小后的256 X 256图片的路径,为了“赛”后可以看到我们转化出来的图片长啥样,所以我就把它保存到了本地了,以至于有了上面略显丑陋的代码。51Testing软件测试网+}(e-?Cy'VG

步骤2,计算图像的直方图

0X:?:v4yK0

publicint[] GetHisogram(Bitmapimg)51Testing软件测试网j(s)t,LH1n

       {

rJP%l8r.q\B0

           BitmapDatadata = img.LockBits(newSystem.Drawing.Rectangle( 0 , 0 , img.Width , img.Height ),ImageLockMode.ReadWrite ,PixelFormat.Format24bppRgb );51Testing软件测试网%r^Y[$~S#G

           int[ ] histogram =newint[ 256 ];

2{ [p$R+ESPa l0

           unsafe51Testing软件测试网't2C*oi-Q

           {51Testing软件测试网{"yF/v#m0H7\V

                               byte* ptr = (byte* )data.Scan0;51Testing软件测试网 Wa%Yq}:Z

                               intremain = data.Stride - data.Width * 3;

PIWH:XWyx?G0

                               for(inti = 0 ; i < histogram.Length ; i ++ )

@:P:HS z1fMQ0A/D0

                                       histogram[ i ] = 0;51Testing软件测试网t3d` o2DQg(zo

                               for(inti = 0 ; i < data.Height ; i ++ )

;i/pg0[!K*Y/r v3l-M0

                               {

h qdAY0

                                       for(intj = 0 ; j < data.Width ; j ++ )51Testing软件测试网G6S2]-i R:E!v

                                       {

o;TAMe6z0

                                               intmean = ptr[ 0 ] + ptr[ 1 ] + ptr[ 2 ];

7c[xj%qQ0

                                               mean /= 3;51Testing软件测试网[a2vvYF f~

                                               histogram[ mean ] ++;51Testing软件测试网0jB3n2e~Y1_;xF7d

                                               ptr += 3;51Testing软件测试网u`E!e)wC-W+e

                                       }51Testing软件测试网 kQ+`vIW

                                       ptr += remain;

3yp LvDaJHJ-?0

                               }

G aTY!MF?o Dwl0

           }

1YQ5h H'r/_;A;O5fc [0

                       img.UnlockBits( data ); 51Testing软件测试网,K8|#X iJsFd\

           returnhistogram;

lw%[|X@G/d0

   }

} ^*_ O0J'm\m0

这段就是惊天地泣鬼神的灰度直方图计算方法,里面的弯弯绕还是留给诸位自己去掺和。

gW%r~3e{F/r0

步骤3,计算直方图相似度度量

pd)y9w$o$l*@~b:`0

这一步骤的法宝在于这个:

q^!N!Nv,K(p;t0

Sim(G,S)=HowTo其中G,S为直方图,N为颜色空间样点数51Testing软件测试网;\%l*z$j8V7W]$m&u

为了大家少敲两行字儿,也给出一堆乱七八糟的代码:

h]Fw[S+G0

 

1OJ'R;|1h j#P{0

//计算相减后的绝对值

7|0P2E,\EF0

       privatefloatGetAbs(intfirstNum,intsecondNum)

2g#@ubK0

       {

-q i |W!Ap!Ap6d(p0

           floatabs =Math.Abs((float)firstNum - (float)secondNum);51Testing软件测试网5fJ;\MY}b

           floatresult =Math.Max(firstNum, secondNum);

fB9?5@;HVo_7v'g0

           if(result == 0)51Testing软件测试网/tH%Ik.OA?+_

               result = 1;

M4yem7z2`6cM0

           returnabs / result;51Testing软件测试网QtFa|g-k

       }51Testing软件测试网w%Lq@ xwC&C;l

 

J-`(W+HTG0

       //最终计算结果

W(GW#qU3DT0

       publicfloatGetResult(int[] firstNum,int[] scondNum)51Testing软件测试网1t(w4Z tZq}4K2B/f

       {51Testing软件测试网7Z#cU'w'e(VEV3C

           if(firstNum.Length != scondNum.Length)51Testing软件测试网N+S e%n{X)Lu

           {

)q.{4Q Q4n0

               return0;

w.tP[+K`"l f9~0

           }

5v0qLQk;@z%| b0

           else51Testing软件测试网 D(_4vXc7`

           {

1k%[!h+F(m*pt0

               floatresult = 0;51Testing软件测试网.JS8c Y5y

               intj = firstNum.Length;51Testing软件测试网6M8U'^4Z {D Cn

               for(inti = 0; i < j; i++)

e-K7U/d$cN0

               {51Testing软件测试网A*Eud/\Gk

                   result += 1 - GetAbs(firstNum[i], scondNum[i]);

|LQ5tg-F0

                   Console.WriteLine(i +"----"+ result);

x$M ex#v0

               }

&U"k?W"B0

               returnresult/j;51Testing软件测试网4|%F/_il.H'c\A

           }51Testing软件测试网 t7D N} OK?

TAG: 图像相似度

 

评分:0

我来说两句

Open Toolbar