该方法获得两张图片。一个是来自资源的同一个图像。 第二个是下载的图像,可能与资源中的图像相同或不同。 然后该方法返回tre或false。
//*** This function compare images region specific area ( in this case the "radar close" text area ) ***\\
public bool ImageComparison(Bitmap Image1, Bitmap Image2, Rectangle Rect, double tol)
{
//Logger.Write("Rect >>>> " + Rect.ToString());
double color_distance;
int x;
int y;
bool different = false;
textbox3 = Rect.ToString();
//if pictures are not of same size, return that they are different
if (Image1.Width != Image2.Width || Image1.Height != Image2.Height)
{
Logger.Write("Image1 Width >>>> " + Image1.Width.ToString());
Logger.Write("Image2 Width >>>> " + Image2.Width.ToString());
Logger.Write("Image1 Height >>>> " + Image1.Height.ToString());
Logger.Write("Image2 Height >>>> " + Image2.Height.ToString());
Logger.Write("Returned False images were different size");
MessageBox.Show("Images are different Size");
textbox1 = "";
textbox2 = "";
textbox3 = "";
return false;
}
//Iterate over the Rect
for (x = Rect.X; x < Rect.X + Rect.Width; ++x)
{
for (y = Rect.Y; y < Rect.Y + Rect.Height; ++y)
{
//check, if x and y are inside the picture
if (x >= 0 && x < Image1.Width && y >= 0 && y < Image1.Height &&
x < Image2.Width && y < Image2.Height)
{
Color c = Image1.GetPixel(x, y);
textbox1 = c.ToString();
Color c2 = Image2.GetPixel(x, y);
textbox2 = c2.ToString();
double Dr = c.R - c2.R;
double Dg = c.G - c2.G;
double Db = c.B - c2.B;
color_distance = Math.Sqrt(Dr * Dr + Dg * Dg + Db * Db);
if (color_distance > tol)
{
different = true;
break;
}
}
else
{
throw new Exception(" Hello!! your region is way off!!!.. major bug!");
}
}
if (different)
break;
}
//Logger.Write("differenet bool is now >>>> " + different.ToString());
return !different;
}
问题在于我使用的是GetPixel和SetPixel,在某些下载的图片上可能会太慢。所以我想把它改成LockBits。 第二件事是我想改变方法,所以它现在将获得3个图像不仅2个,第三个图像也将来自资源。
这就是我在form1中使用方法的方式:
if (ImagesComparion1.ImageComparison(File1, file2, image_scan_text_rect, 50) == true)
{
File1.Dispose();
Properties.Resources.RadarImageClose.Dispose();
label18.Text = "The Radar Is Not Active Now";
label18.Visible = true;
}
else
{
File1.Dispose();
Properties.Resources.RadarImageClose.Dispose();
label18.Text = "The Radar Is Active Now";
label18.Visible = true;
}
file2是来自资源的图片:
file2 = Properties.Resources.RadarImageClose;
File1是下载的图片:
File1 = new Bitmap(Properties.Resources.RadarImageClose);
现在我想改变方法来做这件事:
使用LockBits代替GetPixel和SetPixel。
获取3张图片并进行两个比较过程:
首先在第一个资源图像文件2和File1之间进行比较,然后在方法中进行另一个比较过程,将文件3(也是资源图像)与File1进行比较。
我将方法顶部更改为:
public bool ImageComparison(Bitmap Image1, Bitmap Image2, Bitmap Image3, Bitmap Image4, Rectangle Rect, double tol)
Image1 Image 3和Image4都来自资源获取资源图片。 Image2是下载的图像。
我需要使用LockBits并首先将Image1与Image2进行比较,然后将Image3与Image2进行比较,然后将Image4与Image2进行比较。
如果其中一个比较结果为真,那么如果所有比较都返回结果为false,则该方法返回true而不进行其余的比较。该方法返回false。
这是一个测试我确实拿了3个pictureBoxes并放在左边和中间的图像里面的文字都有不同的文字,但两者都意味着雷达很接近。在右边,我有雷达打开的图像。我在同一区域的所有区域上绘制一个红色矩形,它们都在同一区域。
答案 0 :(得分:1)
使用此功能比较两个图像:
private bool ImageComparison(Bitmap Image1, Bitmap Image2, Rectangle Rect, double tol)
{
int x, y, p, stride1, stride2;
int bytes, bytesPerPixel;
byte[] rgbValues1;
byte[] rgbValues2;
double Dr, Dg, Db, color_distance;
IntPtr ptr;
Rectangle rect;
BitmapData bitmap_Data;
if ( (Image1.Width != Image2.Width) || (Image1.Height != Image2.Height) )
{
MessageBox.Show("Images are different Size");
return false;
}
if (Rect.X < 0 || Rect.Y < 0 || ((Rect.X + Rect.Width) > Image1.Width) || ((Rect.Y + Rect.Height) > Image1.Height))
{
MessageBox.Show("Hello!! your region is way off!!!.. major bug!");
return false;
}
rect = new Rectangle(0, 0, Image1.Width, Image1.Height);
//Lock bitmap to copy its color information fast
bitmap_Data = Image1.LockBits(rect, ImageLockMode.ReadWrite, Image1.PixelFormat);
ptr = bitmap_Data.Scan0;
stride1 = bitmap_Data.Stride;
bytes = bitmap_Data.Stride * Image1.Height;
rgbValues1 = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues1, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
Image1.UnlockBits(bitmap_Data);
rect = new Rectangle(0, 0, Image2.Width, Image2.Height);
//Lock bitmap to copy its color information fast
bitmap_Data = Image2.LockBits(rect, ImageLockMode.ReadWrite, Image2.PixelFormat);
ptr = bitmap_Data.Scan0;
stride2 = bitmap_Data.Stride;
bytes = bitmap_Data.Stride * Image2.Height;
rgbValues2 = new byte[bytes];
//copy color information to rgbValues array
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues2, 0, bytes);
//we are done copying so unlock bitmap. We dont need it anymore
Image2.UnlockBits(bitmap_Data);
if (stride1 != stride2) //different pixel format
{
MessageBox.Show("Different pixel format");
return false;
}
bytesPerPixel = Image.GetPixelFormatSize(Image1.PixelFormat) / 8;
//scan images pixel per pixel
for (y = 0; y < Image1.Height; y++)
{
for (x = 0; x < Image1.Width; x++)
{
p = y * stride1 + x * bytesPerPixel;
Dr = (double)(rgbValues1[p + 2] - rgbValues2[p + 2]);
Dg = (double)(rgbValues1[p + 1] - rgbValues2[p + 1]);
Db = (double)(rgbValues1[p] - rgbValues2[p]);
color_distance = Math.Sqrt(Dr * Dr + Dg * Dg + Db * Db);
if (color_distance > tol)
{
return false;
}
}
}
return true;
}
如果要比较多个,请将它们插入列表:
List<Bitmap> bitmapListToCompare = new List<Bitmap>();
bitmapListToCompare.Add(....);
bitmapListToCompare.Add(....);
....
然后:
int i;
bool bl;
Bitmap bitmapToCompareWith = new Bitmap(...); //your bitmap to use as reference
//for your comparisons
for (i = 0; i < bitmapListToCompare.Count; i++)
{
bl = ImageComparison(bitmapToCompareWith, bitmapListToCompare[i], ...., ....);
if (bl == false)
{
MessageBox.Show("Image " + i.ToString() + " was different!");
break;
}
}