c#灰度直方图算法及调用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
颜色直方图
颜色直方图是在许多图像检索系统中被广泛采用的颜色特征,它所描述的是不同色彩在整福图像中所占的比例,而并不关心每种色彩所处的空间位置,即无法描述图像中的对象或物体。颜色直方图特别适用于描述那些难以进行自动分割的图像
灰度直方图
灰度直方图是灰度级的函数,它表示图像中具有每种灰度级的像素的个数,反映图像中每种灰度出现的频率。灰度直方图的横坐标是灰度级,纵坐标是该灰度级出现的频率,是图像的最基本的统计特征。
灰度直方图的算法实现
大致步骤如下:
1.将图像转换成相同大小,以有利于计算出想象的直方图来
2.计算转化后的会度直方图
3.利用xx公式,得到直方图相似度的定量度量
4.输出这些不知道有用没用的相似度结果数据
代码实现
步骤1.将图像转化成相同大小,我们暂且转化成256×256吧
public static 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);
}
解释一下:imageFile是原始图片的完整路径,newImageFile是强制转换大小后的256×256图片的路径,为了“赛”后可以看到我们转化出来的图片长啥样,所以我就把它保存到了本地了,以至于有了上面的代码
步骤2.计算图像的直方图
///
/// 灰度直方图计算方法
///
///
///
public static int[] GetHisogram(Bitmap img)
{
System.Drawing.Imaging.BitmapData data = img.LockBits(new System.Drawing.Rectangle(0, 0, img.Width, img.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite,
System.Drawing.Imaging.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 { for(int j=0;j { int mean = ptr[0] + ptr[1] + ptr[2]; mean /= 3; histogram[mean]++; ptr += 3; } ptr += remain; } } img.UnlockBits(data); return histogram; } 步骤3.计算直方图相似度度量 这一步骤的法宝在于这个 Sim(G,S)= (好像是欧氏距离公式,不清楚)其中G,S为直方图,N为颜色空间样点数为了大家少敲两行字儿,也给出一堆代码 /// ///计?算?相à减?后ó绝?对?值μ /// /// /// /// private static 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 static float GetResult(int[] firstNum, int[] secondNum) { if (firstNum.Length != secondNum.Length) { return 0; } else { float result = 0; int j = firstNum.Length; for (int i = 0; i < j; i++) { result += 1 - GetAbs(firstNum[i], secondNum[i]); } return result / j; } } 步骤4 输出 调用的时候是这样的调用的 public MainWindow() { InitializeComponent(); //448前° 448后ó 0.6946089 //418后ó 448后ó 0.81816417 //418前° 448前° 0.766890645 //468 468红ì 0.192232266 //468黄? 468红ì 0.286766857 //448前° 448前° 1.0 int[] firstNum = GetHisogram(Resize("C:\\Img\\448.jpg", "C:\\Img\\NewImg\\448.jpg")); int[] secondNum = GetHisogram(Resize("C:\\Img\\418.jpg", "C:\\Img\\NewImg\\418.jpg")); float result = GetResult(firstNum, secondNum); }