图片比较算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图片比较算法
前几天其他项目组接了个项目,客户那边要求顺便给做个图片比较的工具,因为他们要看看同样的网页在IE7和IE8上显示有什么不同,不同的地方用用户指定的某种颜色标示出来,生成第三张图片。因为他们组比较忙,就帮他们做了做,UI界面就不用说了。
起初的想法是这样,先比较两幅图片的hash散列,如果相同就不比较了,下面就是这个算法:
{
img = Image.FromFile(imageFile);
Bitmap imgOutput = new Bitmap(img, 256, 256);
imgOutput.Save(newImageFile, System.Drawing.Imaging.ImageFormat.Jpeg);
imgOutput.Dispose();
SHA256Managed managed = new SHA256Managed();
byte[] buffer3 = managed.ComputeHash(buffer);
byte[] buffer4 = managed.ComputeHash(buffer2);
for (int i = 0; (i < buffer3.Length) && (i < buffer4.Length); i++)
byte[] buffer2 = new byte[1];
ImageConverter converter = new ImageConverter();
buffer = (byte[])converter.ConvertTo(leftImage, buffer.GetType());
buffer2 = (byte[])converter.ConvertTo(rightImage, buffer2.GetType());
}
else
{
rightImage = BitMapAdapter.ResizeImage(rБайду номын сангаасghtImage, leftImage.Width, leftImage.Height);
}
if (!HashCompare(leftImage, rightImage))
{
BitmapData leftBitmapdata = leftImage.LockBits(new Rectangle(0, 0, leftImage.Width,leftImage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
基本知识介绍
颜色直方图
颜色直方图是在许多图像检索系统中被广泛采用的颜色特征,它所描述的是不同色彩在整幅图像中所占的比例,而并不关心每种色彩所处的空间位置,即无法描述图像中的对象或物体。颜色直方图特别适用于描述那些难以进行自动分割的图像。
灰度直方图
灰度直方图是灰度级的函数,它表示图像中具有每种灰度级的像素的个数,反映图像中每种灰度出现的频率。灰度直方图的横坐标是灰度级,纵坐标是该灰度级出现的频率,是图像的最基本的统计特征。
private static bool HashCompare(Bitmap leftImage, Bitmap rightImage)
{
if (leftImage.Size != rightImage.Size)
{
return false;
}
byte[] buffer = new byte[1];
}
else
{
return true;
}
}
但是最后又出来个问题,因为对同一个网页,IE7跟IE8上显示的竟然不是同一个尺寸,最后就又加了一个调整尺寸的函数(上面红色的就是后来加的),调整函数如下:
/// <summary>
/// Resize bitmap
/// </summary>
/// <param name="bmp">original Bitmap</param>
unsafe
{
byte* leftImageDataPointer = (byte*)(leftBitmapdata.Scan0.ToPointer());
byte* rightImageDataPointer = (byte*)(rightBitmapdata.Scan0.ToPointer());
本文中即是使用灰度直方图来计算图片相似度,关于算法那一块也不赘言了,毕竟图像学图形学,直方图我是门儿都不懂,我也不准备打肿脸充胖子,只想实现一个最基本的算法,然后从最直观的角度看看这个算法的有效性,仅此而已。
算法实现
诸位看官休怪笔者囫囵吞枣,浅尝辄止的学习态度。额毕竟是因兴趣而来,于此方面并无半点基础(当然,除了知道RGB是啥玩意儿——这还幸亏当年计算机图形学的老师是个Super美女,因此多上了几节课的缘故),更谈不上半点造诣,看官莫怪莫怪,且忍住怒气,是走是留,小生不敢有半点阻拦~~
Math.Abs((int)leftImageDataPointer[1] - (int)rightImageDataPointer[1]) > RGBDifference &&
Math.Abs((int)leftImageDataPointer[2] - (int)rightImageDataPointer[2]) > RGBDifference)
{
if (buffer3[i] != buffer4[i])
{
return false;
}
}
return true;
}
如果hash散列不同,就挨个像素比较,可这样有个问题,就是两幅图片有时候其实我们看起来是一样的,但是实际上你取他们像素的时候他们是不同的,如果我们将用户都不能分辨出不同的地方都标示出来意义不大,于是最后决定只比较像素的R.G.B,只要他们相同就行(这里的相同也做了妥协,就是两个像素的R.G.B值也允许有一定的误差),最后算法如下:
闲言碎语
才疏学浅,只把计算图像相似度的一个基本算法的基本实现方式给罗列了出来,以至于在最后自己测评的时候也大发感慨,这个算法有点不靠谱。不管怎么样,这个算法有时候还是有用的,所以还是列出来跟大家伙一起分享分享~~
PS:图像处理这一块博大精深,个人偶尔发现了点东西拿来分享。说的不好的地方,写得太糟的地方,诸位准备扔砖头还望淡定,淡定~~
/// <param name="resultImageFullPath">the result bitmap</param>
/// <returns>return the comparision result</returns>
public static bool Compare(Bitmap leftImage, Bitmap rightImage, string resultImageFullPath)
大致步骤如下:
1, 将图像转换成相同大小,以有利于计算出相像的直方图来
2, 计算转化后的灰度直方图
3, 利用XX公式,得到直方图相似度的定量度量
4, 输出这些不知道有用没用的相似度结果数据
代码实现
步骤1,将图像转化成相同大小,我们暂且转化成256 X 256吧。
public Bitmap Resize(string imageFile, string newImageFile)
graph.Dispose();
return bmap;
}
catch
{
return null;
}
}
图像相似度算法的C#实现及测评
原文来自:雨枫技术教程网http://www.fengfly.com
原文网址:http://www.fengfly.com/plus/view-140639-1.html
近日逛博客的时候偶然发现了一个有关图片相似度的Python算法实现。想着很有意思便搬到C#上来了,给大家看看。
/// <summary>
/// compare two bitmaps.
/// </summary>
/// <param name="leftImage">the first bitmap</param>
/// <param name="rightImage">the second bitmap</param>
/// <summary>
/// compare the hash value of two image files.
/// </summary>
/// <param name="leftImage"></param>
/// <param name="rightImage"></param>
/// <returns></returns>
}
}
leftImage.UnlockBits(leftBitmapdata);
rightImage.UnlockBits(rightBitmapdata);
if (!matched)
{
leftImage.Save(resultImageFullPath, ImageFormat.Jpeg);
}
return matched;
}
leftImageDataPointer += 3;
rightImageDataPointer += 3;
}
leftImageDataPointer += leftBitmapdata.Stride - leftBitmapdata.Width * 3;
rightImageDataPointer += rightBitmapdata.Stride - rightBitmapdata.Width * 3;
{
try
{
Bitmap bmap = new Bitmap(newW, newH);
Graphics graph = Graphics.FromImage(bmap);
graph.InterpolationMode = InterpolationMode.HighQualityBicubic;
graph.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width,bmp.Height), GraphicsUnit.Pixel);
for (int y = 0; y < leftBitmapdata.Height; y++)
{
for (int x = 0; x < leftBitmapdata.Width; x++)
{
if (Math.Abs((int)leftImageDataPointer[0] - (int)rightImageDataPointer[0]) > RGBDifference &&
{
matched = false;
leftImageDataPointer[0] = (byte)mismatchedColor.B;
leftImageDataPointer[1] = (byte)mismatchedColor.G;
leftImageDataPointer[2] = (byte)mismatchedColor.R;
{
bool matched = true;
//if the two bitmaps are not the same size,then resize the large one.
if (leftImage.Height > rightImage.Height)
{
leftImage = BitMapAdapter.ResizeImage(leftImage, rightImage.Width, rightImage.Height);
BitmapData rightBitmapdata = rightImage.LockBits(new Rectangle(0, 0, rightImage.Width, rightImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
/// <param name="newW">new width</param>
/// <param name="newH">new height</param>
/// <returns>worked bitmap</returns>
public static Bitmap ResizeImage(Bitmap bmp, int newW, int newH)
相关文档
最新文档