32、计算机视觉中的机器学习:SVM、HOG与深度学习

计算机视觉中的机器学习:SVM、HOG与深度学习

1. 支持向量机(SVM)基础

支持向量机(SVM)在简单分类问题上计算较为简单,但对于更具挑战性的分类问题,核函数是非常有效的工具。OpenCV提供了多种标准核函数,如径向基函数、Sigmoid函数等,其目的是将样本映射到更大的非线性空间,使类别能够通过超平面分离。

SVM有多种变体,最常见的是C - SVM,它会对每个不在超平面正确一侧的异常样本添加惩罚项。由于SVM具有强大的数学基础,它在处理高维特征时表现出色,尤其是当特征空间的维度大于样本数量时,性能最佳。此外,SVM还具有内存效率高的优点,因为它只需要存储支持向量,而不像最近邻方法那样需要在内存中保存所有样本点。

2. HOG与SVM的结合

方向梯度直方图(HOG)和SVM是构建优秀分类器的良好组合。HOG可以被视为一种强大的高维描述符,能够捕捉对象类别的本质特征。HOG - SVM分类器已成功应用于许多领域,行人检测就是其中之一。

2.1 HOG可视化

HOG由重叠块中的单元格组成,因此很难直接可视化这个描述符。通常,通过显示每个单元格关联的直方图来表示HOG。在这种情况下,方向直方图可以更直观地绘制为星形,其中每条线的方向与它所代表的区间相关,线的长度与该区间的计数成正比。

以下是绘制单个单元格HOG的代码:

//draw one HOG over one cell 
void drawHOG(std::vector<float>::const_iterator hog,  
                   // iterator to the HOG 
             int numberOfBins,       // number of bins inHOG 
             cv::Mat &image,         // image of the cell 
             float scale=1.0) {      // length multiplier 

  const float PI = 3.1415927; 
  float binStep = PI / numberOfBins; 

  float maxLength = image.rows; 
  float cx = image.cols / 2.; 
  float cy = image.rows / 2.; 

  // for each bin 
  for (int bin = 0; bin < numberOfBins; bin++) { 

    // bin orientation 
    float angle = bin*binStep; 
    float dirX = cos(angle); 
    float dirY = sin(angle); 
    // length of line proportion to bin size 
    float length = 0.5*maxLength* *(hog+bin); 

    // drawing the line 
    float x1 = cx - dirX * length * scale; 
    float y1 = cy - dirY * length * scale; 
    float x2 = cx + dirX * length * scale; 
    float y2 = cy + dirY * length * scale; 
    cv::line(image, cv::Point(x1, y1), cv::Point(x2, y2),  
             CV_RGB(255, 255, 255), 1); 
  } 
} 

以下是在图像上绘制HOG描述符的代码:

// Draw HOG over an image 
void drawHOGDescriptors(const cv::Mat &image,  // the input image  
         cv::Mat &hogImage, // the resulting HOG image 
         cv::Size cellSize, // size of each cell (blocks are ignored) 
         int nBins) {       // number of bins 

  // block size is image size 
  cv::HOGDescriptor hog( 
          cv::Size((image.cols / cellSize.width) * cellSize.width,     
                   (image.rows / cellSize.height) * cellSize.height), 
          cv::Size((image.cols / cellSize.width) * cellSize.width,   
                   (image.rows / cellSize.height) * cellSize.height),  
          cellSize,    // block stride (ony 1 block here) 
          cellSize,    // cell size 
          nBins);      // number of bins 

  //compute HOG 
  std::vector<float> descriptors; 
  hog.compute(image, descriptors); 
  ... 
  float scale= 2.0 / * std::max_element(descriptors.begin(),descriptors.end()); 
  hogImage.create(image.rows, image.cols, CV_8U); 
  std::vector<float>::const_iterator itDesc= descriptors.begin(); 

  for (int i = 0; i < image.rows / cellSize.height; i++) { 
    for (int j = 0; j < image.cols / cellSize.width; j++) {  
      //draw each cell 
      hogImage(cv::Rect(j*cellSize.width, i*cellSize.height,  
                        cellSize.width, cellSize.height)); 
      drawHOG(itDesc, nBins,  
              hogImage(cv::Rect(j*cellSize.width,              
                                i*cellSize.height,  
                                cellSize.width, cellSize.height)),  
              scale); 
      itDesc += nBins; 
    } 
  } 
} 

这个函数计算具有指定单元格大小但仅由一个大的块(即块的大小等于图像大小)组成的HOG描述符,因此忽略了每个块级别的归一化效果。

2.2 行人检测

OpenCV提供了基于HOG和SVM的预训练行人检测器。与之前的分类器级联一样,这个SVM分类器可以通过在图像上以多个尺度扫描窗口来检测整幅图像中的实例。以下是使用该检测器的代码:

// create the detector 
std::vector<cv::Rect> peoples; 
cv::HOGDescriptor peopleHog; 
peopleHog.setSVMDetector( 
cv::HOGDescriptor::getDefaultPeopleDetector()); 
// detect peoples oin an image 
peopleHog.detectMultiScale(myImage, // input image 
           peoples,           // ouput list of bounding boxes  
           0,       // threshold to consider a detection to be positive 
           cv::Size(4, 4),    // window stride  
           cv::Size(32, 32),  // image padding 
           1.1,               // scale factor 
           2);                // grouping threshold 

窗口步长定义了128×64模板在图像上的移动方式(在我们的示例中,水平和垂直方向每4个像素移动一次)。较长的步长会使检测速度更快,但可能会错过一些位于测试窗口之间的行人。图像填充参数会在图像边界添加像素,以便检测图像边缘的行人。

SVM分类器的标准阈值为0(因为正实例赋值为1,负实例赋值为 - 1)。如果要确保检测到的是行人,可以提高阈值,但这可能会错过一些行人;反之,如果要确保检测到所有行人,可以降低阈值,但会增加误检的可能性。

当分类器应用于整幅图像时,在连续位置应用的多个窗口通常会在正样本周围产生多个检测结果。当两个或更多边界框在大致相同的位置重叠时,最好只保留其中一个。 cv::groupRectangles 函数可以将相似大小、相似位置的矩形合并, detectMultiScale 方法会自动调用该函数。

3. 深度学习与卷积神经网络

在机器学习领域,不能不提及深度卷积神经网络(CNN)。将其应用于计算机视觉分类问题已经取得了令人瞩目的成果,其在实际问题中的出色表现为以前无法想象的新应用领域打开了大门。

3.1 深度学习兴起的原因

深度学习基于20世纪50年代末引入的神经网络理论,如今之所以受到广泛关注,主要有两个原因:
- 计算能力的提升:如今可用的计算能力使得部署能够解决挑战性问题的大型神经网络成为可能。早期的神经网络(如感知机)只有一层,需要调整的权重参数很少,而现在的网络可以有数百层和数百万个需要优化的参数,因此被称为深度网络。
- 大量数据的可用性:深度学习网络需要数千甚至数百万个带注释的样本进行训练,因为需要优化的参数数量非常大。如今大量的数据使得深度学习网络的训练成为可能。

3.2 卷积神经网络(CNN)

最流行的深度网络是卷积神经网络(CNN),顾名思义,它基于卷积操作。在这种情况下,需要学习的参数是组成网络的所有滤波器内核中的值。这些滤波器按层组织,早期层提取基本形状,如线条和角点,而较高层则逐渐检测更复杂的模式,例如在人体检测器中检测眼睛、嘴巴、头发的存在。

OpenCV 3有一个深度神经网络模块,但主要用于导入使用其他工具(如TensorFlow、Caffe或Torch)训练的深度网络。在构建未来的计算机视觉应用时,需要了解深度学习理论及其相关工具。

3.3 相关操作参数说明

参数 说明
窗口步长 定义模板在图像上的移动方式,较长步长检测快但可能漏检
图像填充 在图像边界添加像素,便于检测边缘行人
阈值 标准为0,提高阈值精度高但可能漏检,降低阈值召回率高但误检多
分组阈值 detectMultiScale 的最后一个参数,用于合并重叠检测框

3.4 行人检测流程

graph TD;
    A[创建HOG描述符] --> B[设置SVM检测器];
    B --> C[进行多尺度检测];
    C --> D[输出检测结果];

综上所述,HOG与SVM的结合在目标检测领域有着重要的应用,而深度学习和卷积神经网络则为计算机视觉带来了新的发展方向。在实际应用中,可以根据具体需求选择合适的方法和工具。

4. 总结与应用建议

4.1 不同方法的优势总结

  • SVM :具有强大的数学基础,在处理高维特征时表现出色,尤其是特征空间维度大于样本数量的情况。内存效率高,只存储支持向量。对于一些复杂的分类问题,通过核函数可以将样本映射到高维空间,使类别可分。
  • HOG - SVM :HOG能够捕捉对象类别的本质特征,与SVM结合后在行人检测等应用中取得了很好的效果。HOG可视化可以帮助我们更好地理解其特征表示。
  • 深度学习与CNN :在计算机视觉分类问题上取得了令人瞩目的成果,能够处理复杂的模式和大规模数据。随着计算能力的提升和数据的丰富,CNN的应用前景非常广阔。

4.2 应用场景选择建议

应用场景 建议方法 原因
高维特征且样本数量相对较少 SVM SVM在这种情况下性能最佳,内存效率高
行人检测等目标检测任务 HOG - SVM HOG能捕捉目标本质特征,结合SVM可有效检测目标
复杂的图像分类、识别任务 深度学习与CNN CNN能够自动学习复杂的模式,处理大规模数据

4.3 操作步骤总结

4.3.1 HOG可视化操作步骤
  1. 定义绘制单个单元格HOG的函数 drawHOG ,根据方向和区间计数绘制星形直方图。
  2. 定义在图像上绘制HOG描述符的函数 drawHOGDescriptors ,计算HOG描述符并调用 drawHOG 函数绘制每个单元格。
4.3.2 行人检测操作步骤
  1. 创建HOG描述符 cv::HOGDescriptor
  2. 设置SVM检测器为默认行人检测器 setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector())
  3. 调用 detectMultiScale 方法进行多尺度检测,设置窗口步长、图像填充、阈值、缩放因子和分组阈值等参数。
  4. 处理检测结果,可使用 cv::groupRectangles 函数合并重叠的检测框。

4.4 未来发展趋势

随着技术的不断发展,深度学习和卷积神经网络将在计算机视觉领域发挥越来越重要的作用。一方面,网络结构会不断优化,以提高性能和效率;另一方面,数据的规模和质量也将不断提升,为模型的训练提供更好的支持。同时,HOG - SVM等传统方法也将在一些特定场景中继续发挥作用,与深度学习方法相互补充。

4.5 注意事项

  • 在使用HOG - SVM进行行人检测时,需要根据实际情况调整窗口步长、阈值等参数,以平衡检测速度和准确性。
  • 深度学习模型的训练需要大量的计算资源和数据,在实际应用中需要考虑成本和可行性。
  • 在使用OpenCV的深度神经网络模块时,要注意导入的模型与工具的兼容性。

总之,计算机视觉中的机器学习方法各有优劣,在实际应用中需要根据具体问题和需求选择合适的方法,并不断探索和优化,以取得更好的效果。无论是传统的SVM和HOG方法,还是新兴的深度学习和CNN技术,都为我们解决计算机视觉问题提供了有力的工具。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值