前言:
这个方法对单一色图片的识别效果其实并不好,准确地说,就是黑白不分。
这是一个相对简单的识别,准确率不高,但可以满足部分需求,然后就是一部分代码是有问题的。
ImageSimilarity.cs:
public class ImageSimilarity
{
public Bitmap Resize(string imageFile, string newImageFile)
{
Image img = Image.FromFile(imageFile);
Bitmap imgOutput = new Bitmap(img, 256, 256);
imgOutput.Save(newImageFile, System.Drawing.Imaging.ImageFormat.Jpeg);
imgOutput.Dispose();
return (Bitmap)Image.FromFile(newImageFile);
}
//灰度直方图计算方法
public int[] GetHisogram(Bitmap img)
{
BitmapData data = img.LockBits(new System.Drawing.Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int[] histogram = new int[256];
unsafe
{
byte* ptr = (byte*)data.Scan0;
int remain = data.Stride - data.Width * 3;
for (int i = 0; i < histogram.Length; i++)
histogram[i] = 0;
for (int i = 0; i < data.Height; i++)
{
for (int j = 0; j < data.Width; j++)
{
int mean = ptr[0] + ptr[1] + ptr[2];
mean /= 3;
histogram[mean]++;
ptr += 3;
}
ptr += remain;
}
}
img.UnlockBits(data);
return histogram;
}
//计算相减后的绝对值
private float GetAbs(int firstNum, int secondNum)
{
float abs = Math.Abs((float)firstNum - (float)secondNum);
float result = Math.Max(firstNum, secondNum);
if (result == 0)
result = 1;
return abs / result;
}
//最终计算结果
public float GetResult(int[] firstNum, int[] scondNum)
{
if (firstNum.Length != scondNum.Length)
{
return 0;
}
else
{
float result = 0;
int j = firstNum.Length;
for (int i = 0; i < j; i++)
{
result += 1 - GetAbs(firstNum[i], scondNum[i]);
Console.WriteLine(i + "----" + result);
}
return result / j;
}
}
}
调用例:
ImageSimilarity sim = new ImageSimilarity();
int[] firstimg=sim.GetHisogram(sim.Resize("[email protected]", "resize_test1.jpeg"));
int[] secondimg = sim.GetHisogram(sim.Resize("dd4.png", "resize_test2.jpeg"));
MessageBox.Show(sim.GetResult(firstimg, secondimg).ToString());
看了下
private float GetAbs(int firstNum, int secondNum)
{
float abs = Math.Abs((float)firstNum - (float)secondNum);
float result = Math.Max(firstNum, secondNum);
if (result == 0)
result = 1;
return abs / result;
}
这段代码有误,原文应该是计算在RGB空间中的间距,在RGB中的R上相邻的两点直接相减差值可能非常巨大,直接用减法做分子是不对的。
参考来源:
https://www.cnblogs.com/wuchaodong/archive/2009/04/28/1444792.html