65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 的计算机视觉应用 - 第一部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (29投票s)

2009年4月15日

CPOL

6分钟阅读

viewsIcon

109843

downloadIcon

5424

应用计算机视觉简介。

article.png

引言

计算机视觉与编程相辅相成。需要利用编程来实现理论,以便将其应用于现实世界的问题。计算机视觉是一个令人兴奋的领域,我们试图从中理解图像。这些图像可以是静态的,也可以是从视频中获取的。理解可能包括跟踪物体、对背景进行建模、识别模式等。本文是系列文章的第一篇,我将使用 C# 来向用户介绍计算机视觉。作为第一篇文章,我打算介绍一些计算机视觉中的基本概念。我将在后续的文章中引用这些概念,届时我将实现一些最先进的计算机视觉算法,涵盖物体跟踪、背景建模、模式识别等领域。

图像理解

图像由许多称为像素(Picture Elements)的点组成。像素越多,图像的分辨率越高。当相机捕捉到图像时,它通常是RGB(红绿蓝)格式。RGB 是计算机视觉中使用的众多色彩空间之一。其他色彩空间包括 HSV、Lab、XYZ、YIQ 等。RGB 是一种加色模型,我们通过混合红色、绿色和蓝色值来获得不同的颜色。在 24 位 RGB 图像中,R、G 和 B 分量的单个值范围从 0 到 255。24 位 RGB 图像可以表示 224 种不同的颜色,即 1600 万种。好的,回到图像,我们人类可以看到其中的物体,而计算机看到的是 RGB 值范围从 0 到 255 的像素。因此,显然需要为计算机构建某种智能,以便我们能够让它们理解图像。

如果您想在计算机视觉领域发展职业,您必须理解一件事:统计与概率!通常,统计学用于创建模型,而概率用于理解模型。所以,接下来,我将尝试解释一些理解图像所需的基础知识,以便可以将其应用于计算机视觉技术。

图像属性

对图像进行建模的第一步是选择要建模的属性。它不一定是一个单一属性——您通常会使用属性的组合来使您的算法更健壮。一些主要属性包括边缘、颜色等。选择这些属性是因为它们是唯一的。但实际上并非如此。例如,如果使用颜色,许多图像将共享相同的颜色分布。因此,我们需要找到一个或一组属性,它们提供更大的独特性。

使用直方图进行属性建模

选择好属性后,下一步就是对其进行建模。计算机视觉中有许多可用的模型——每个模型都有其优缺点。但在这篇文章中,我将专注于直方图。选择直方图的原因是它在计算机视觉中非常流行,并且它构成了后续文章的基础。从初等统计学中,我们知道直方图无非就是频率分布。因此,颜色直方图就是图像中不同颜色的频率。

通过归一化,我们可以为直方图添加尺度不变性。这意味着具有不同尺度的同一对象将具有相同的直方图。通过将每个 bin 的值除以 bin 的总值来实现归一化。

要创建颜色直方图,我们首先需要决定直方图的 bin 数量。总的来说,bin 越多,鉴别能力越强。但是,另一方面,您需要更多的计算资源。第二个需要做出的决定是如何实现此颜色直方图。请记住,通常会有三种颜色分量,例如红色、绿色和蓝色。一种流行的方法是使用 3D 数组或单个数组。使用 3D 数组很简单,但为三个分量使用单个数组需要仔细考虑。最终,这取决于个人喜好——我更喜欢后一种方法。

对于 16x16x16 bin 的直方图,每个 bin 有 256/16 = 16 种颜色分量。所以,我们定义一个 3D 数组,如下所示

// Declare a 3 dimensional histogram
[,,] float histogram = new float [16, 16, 16];

例如,如果像素的 RGB 值为 13、232 和 211,那么这意味着您正在处理 RGB bin 0、14 和 13。这些 bin 号是通过将颜色值除以 bin 数(在本例中为 16)得到的。您需要将直方图 [0, 14, 15] 加 1。如果我们对图像中的所有像素执行此操作,我们将得到图像的颜色直方图,它告诉我们图像中的颜色分布。

对于 16x16x16 bin 的直方图,我们声明一个 1D 数组,如下所示

// Declare a 1 dimensional histogram
[] float histogram = new float [16 * 16 * 16];

为了使用 1D 数组,我们需要定义一个索引方案,以便我们可以添加和检索 bin 的值。索引方法在下面的代码中给出

private int GetSingleBinIndex(int binCount1, int binCount2, int binCount3, BGRA* pixel)
{
    int idx = 0;
    
    //find the index
    int i1 = GetBinIndex(binCount1, (float)pixel->red, 255);
    int i2 = GetBinIndex(binCount2, (float)pixel->green, 255);
    int i3 = GetBinIndex(binCount3, (float)pixel->blue, 255);
    idx = i1 + i2 * binCount1 + i3 * binCount1 * binCount2;

    return idx;
}

同样,如果像素的 RGB 值为 13、232 和 211,那么这意味着您正在处理 RGB bin 0、14 和 13。这指向 1D 数组中的索引 0 + 14 x 16 + 13 x 16 x 16 = 3552。要创建直方图,您需要将此 bin 的值加 1。

模型匹配

一旦我们将图像属性表示为直方图,我们通常需要进行识别。因此,我们可以有一个源直方图和一个候选直方图,并匹配直方图以查看候选对象与源对象的相似程度。有许多技术可用,例如 Bhattacharyya 系数、Earth Movers Distance、卡方、欧氏距离等。在本文中,我将介绍 Bhattacharyya 系数。您可以实现自己的匹配技术,请记住,每种匹配技术都有其优缺点。

Bhattacharyya 系数作用于具有相同 bin 数量的归一化直方图。给定两个直方图 p 和 q,Bhattacharyya 系数由下式给出

bc.png

如果您和我一样,会被数学公式吓倒,那么别担心:我有一个带有答案的示例!考虑以下两个直方图,Bhattacharyya 系数的计算如下

h1.png

h2.png

bc_calc.png

正如我们所见,它要求我们将 bin 相乘。此外,我们可以看到,对于相同的直方图,系数将为 1。Bhattacharyya 系数的值范围从 0 到 1,即从最不相似到精确匹配。

Using the Code

  • 步骤 1:选择直方图大小 - 默认值为 4x4x4。
  • 步骤 2:从列表中选择一张图片,然后点击顶部的“<<”按钮查看其直方图。
  • 步骤 3:从列表中选择一张图片,然后点击底部的“<<”按钮查看其直方图。
  • 步骤 4:点击“查找 Bhattacharyya 系数”按钮查看系数。对于相同的图片,系数将为 1。

关注点

在 .NET 中进行本机图像处理是的!使用带有 GetPixel()SetPixel() 方法的 Bitmap 对象不是在 .NET 中进行图像处理的方法。我们需要使用不安全的处理来访问像素数据。我使用了 Eric Gunnerson 的代码。

历史

  • 版本 1.0。
© . All rights reserved.