比较两张图片的差异
来源:互联网 发布:手机测防水软件 编辑:程序博客网 时间:2024/05/13 19:01
工作中经常遇到比较图片的需求,所以去网上搜索了一下,自己写了两个方法:
1. 直接使用Bitmap类对图片的每一个像素进行比较。
优点:简单
缺点:速度慢,当图片尺寸稍大的时候就会很慢(我的方法RemoveSinglePoints性能比较差,当存在差异的像素过多时会花费几十秒)
/// <summary>/// Compare two images./// </summary>/// <param name="img1">The first image path.</param>/// <param name="img2">The second image path.</param>/// <param name="imgDiff">The compare result image path.</param>/// <param name="tolerance">The compare tolerance.</param>/// <returns>If the two image are identical return true, else return false.</returns>private bool CompareImage(string img1, string img2, string imgDiff, int tolerance = 10){ // Load the images. Bitmap bm1 = (Bitmap)Bitmap.FromFile(img1); Bitmap bm2 = (Bitmap)Bitmap.FromFile(img2); // Make a difference image. if (bm1.Width != bm2.Width || bm1.Height != bm2.Height) { Console.WriteLine("Image size are different."); } int wid = bm1.Width; int hgt = bm1.Height; Bitmap bm3 = new Bitmap(bm1); // Create the difference image. Color ne_color = Color.Red; List<Point> differentPoints = new List<Point>(); for (int x = 0; x < wid; x++) { for (int y = 0; y < hgt; y++) { if (!bm1.GetPixel(x, y).Equals(bm2.GetPixel(x, y))) { differentPoints.Add(new Point(x, y)); } } } List<Point> continuousPoints = this.RemoveSinglePoints(differentPoints); if (continuousPoints.Count <= tolerance) { return true; } foreach (var point in continuousPoints) { bm3.SetPixel(point.X, point.Y, ne_color); } bm3.Save(imgDiff); return false;}
/// <summary>/// Remove all single point./// </summary>/// <param name="points">All points.</param>/// <returns>The continus points.</returns>public List<Point> RemoveSinglePoints(List<Point> points){ List<Point> continuousPoints = new List<Point>(); foreach (Point p in points) { var count = points.FindAll(x => Math.Abs(x.X + x.Y - p.X - p.Y) <= 2).Count; if (count > 1) { continuousPoints.Add(p); } } return continuousPoints;}
2. 下面的方法是使用BitmapData对图片进行比较,速度还是很快的。
这个方法的原理就是将整张图片的像素读取到一个列表中,然后比较两个列表的全部内容,发现不同的像素后将其替换为红色(RGB法), 24bit RGB法存储的图片每一个像素为3个字节,第一个字节是蓝色,第二个是绿色,第三个是红色(这个blog讲的很清楚,想详细了解的可以参考一下: http://blog.csdn.net/lulu831110/article/details/4820377/ )
/// <summary>/// Compare two images./// </summary>/// <param name="img1">The first image path.</param>/// <param name="img2">The second image path.</param>/// <param name="imgDiff">The compare result image path.</param>/// <param name="tolerance">The compare tolerance.</param>/// <returns>If the two image are identical return true, else return false.</returns>private bool CompareImageFast(string img1, string img2, string imgDiff, int tolerance = 10){ try { // Load the images. Bitmap bm1 = (Bitmap)Bitmap.FromFile(img1); Bitmap bm2 = (Bitmap)Bitmap.FromFile(img2); int wid = bm1.Width; int hgt = bm1.Height; //// Make a difference image. if (wid != bm2.Width || hgt != bm2.Height) { Console.WriteLine("Image size are different."); } BitmapData data1 = bm1.LockBits(new Rectangle(0, 0, wid, hgt), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData data2 = bm2.LockBits(new Rectangle(0, 0, wid, hgt), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); //// Create the difference image. Color ne_color = Color.Red; int differentPoints = 0; unsafe { //// Get the address of the first line of picture 1. IntPtr ptr1 = data1.Scan0; //// Declare an array to hold the bytes of the bitmap. int bytes = data1.Stride * hgt; byte[] rgbValues1 = new byte[bytes]; //// Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr1, rgbValues1, 0, bytes); //// Get the address of the first line of picture 2. IntPtr ptr2 = data2.Scan0; //// Declare an array to hold the bytes of the bitmap. byte[] rgbValues2 = new byte[bytes]; //// Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr2, rgbValues2, 0, bytes); for (int counter = 0; counter < rgbValues1.Length; counter += 3) { if (rgbValues1[counter] != rgbValues2[counter] || rgbValues1[counter + 1] != rgbValues2[counter + 1] || rgbValues1[counter + 2] != rgbValues2[counter + 2]) { differentPoints++; rgbValues1[counter] = 0; rgbValues1[counter + 1] = 0; rgbValues1[counter + 2] = 255; } } if (differentPoints <= tolerance) { return true; } //// Copy the RGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(rgbValues1, 0, ptr1, bytes); bm1.UnlockBits(data1); //// Save the different picture. bm1.Save(imgDiff); return false; } } catch (Exception exp) { throw exp; }}
0 0
- 比较两张图片的差异
- oracle比较两张相同数据表的差异?
- 比较两张图片的相似程序
- JAVA 比较两张图片的相似度的代码
- ps了两张比较满意的图片
- JAVA 比较两张图片的相似度
- java--比较两张图片的相似度
- 比较两张图片的相似度-python
- android中比较两张图片的相似度
- JAVA 比较两张图片的相似度
- [Java]比较两张图片的相似度
- Python 比较两张图片的相似百分比
- JAVA 比较两张图片的相似度
- 如何实现“比较两张图片的相似度”,或者说“比较两张图片是否基本一致”的算法?
- 比较两数据库的差异
- c#比较两张图片是否相同
- 两张图片相似度比较
- 两张图片的合成
- 生活之感悟
- PHP
- 小记1
- Sass学习之路(10)——注释、数据类型
- 欢迎使用CSDN-markdown编辑器
- 比较两张图片的差异
- Design库-TabLayout属性详解
- oj题目回顾(1992)C语言实验——分数序列
- Linux-vim替换命令
- Codeforces Round #384 (Div. 2) E. Vladik and cards
- Git环境搭建与基本使用方法
- 第十六周 项目3:点结构体(1)
- form表单数据转换为json对象
- 第十六周—C语言 项目二(学生成绩处理)