【问题标题】:Horizontal and vertical edge profiles using python-opencv使用 python-opencv 的水平和垂直边缘轮廓
【发布时间】:2013-03-05 22:15:37
【问题描述】:

我正在尝试检测图像中的车辆(实际上是视频中的一系列帧)。我是 opencv 和 python 新手,在 windows 7 下工作。

有没有办法获取图像的水平边缘和垂直边缘,然后将得到的图像总结为各自的向量?

是否有可用的 Python 代码或函数。

我查看了thisthis,但不知道该怎么做。 您可以使用下图进行说明。

编辑

我受到以下论文中提出的想法的启发(抱歉,如果您没有访问权限)。

贝特克,M.; Haritaoglu, E. & Davis, L. S. Real-time multiple Vehicle detection and tracking from amoving vehicle Machine Vision and Applications, Springer-Verlag, 2000, 12, 69-83

【问题讨论】:

    标签: python opencv computer-vision edge-detection


    【解决方案1】:

    我会看一下 opencv 的正方形示例,发布在here。它使用精明,然后进行轮廓查找以返回每个正方形的边。您应该能够修改此代码以获得您正在寻找的水平和垂直线。 Here 是 canny 的 python 调用文档的链接。它对全方位边缘检测很有帮助。大约一个小时后,我可以回家并给你一个你想要的工作示例。

    【讨论】:

    • 谢谢。我提供的图像(正方形)仅用于说明目的,因为我没有道路上车辆的免费图像
    • 如果您恰好知道车辆后部的样子,并且可以假设它保持相对恒定,那么我建议您使用模板匹配。如果它是恒定的,那么它可能会更准确一些,计算压力也更小。
    • 模板的想法可能会缩小感兴趣的区域。不幸的是,现实生活中的问题不是基本算法友好的。我的视频在路上,我需要识别司机所包围的每一辆车。
    • 可以理解。实际上,大约一年前,我碰巧用 C 语言编写了一个程序,该程序从行车记录仪中检测到车牌。虽然这不是我最终确定的,但模板匹配在那种情况下实际上工作得比较好。需要注意的一点是,对于许多汽车,在它们上检测到的线条并不总是水平和垂直的。您可能希望扩展您的系统以包含某些线条图案。就像一个圆形梯形(挡风玻璃)。
    • 抱歉耽搁了,我比预期的要忙。我想我找到了那篇论文,所以我会在阅读后发布一个示例。
    【解决方案2】:

    阅读 Sobel 过滤器。

    http://en.wikipedia.org/wiki/Sobel_operator

    您基本上可以在每个像素处获得垂直和水平渐变。

    这是它的 OpenCV 函数。

    http://docs.opencv.org/modules/imgproc/doc/filtering.html?highlight=sobel#sobel

    一旦您获得这些过滤后的图像,您就可以按列/行收集统计信息,并确定其是否为边缘并获取该位置。

    【讨论】:

      【解决方案3】:

      对象检测的典型几何方法并不是非常成功,因为您假设的外观模型很容易被遮挡、噪声或方向变化所破坏。

      在我看来,机器学习方法通​​常效果更好,并且可能会为您的问题提供更强大的解决方案。由于您似乎正在使用 OpenCV,您可以查看 Casacade Classifiers,OpenCV 为其提供了一个 Haar 小波和一个基于局部二进制模式特征的分类器。

      我提供的链接是一个教程,其中包含非常完整的步骤,解释了如何使用几个预先编写的实用程序创建分类器。基本上,您将创建一个包含汽车“正面”图像的目录和一个包含典型背景的“负面”图像的目录。实用程序opencv_createsamples 可用于创建扭曲的训练图像,以从一小组图像中模拟不同的方向和平均强度。然后,您可以使用实用程序opencv_traincascade 设置一些命令行参数来选择不同的训练选项,从而为您输出经过训练的分类器。

      检测可以使用 C++ 或 Python 接口与这个经过训练的分类器一起执行。 例如,使用 Python,您可以加载分类器并在图像上执行检测,以获取选择的边界矩形:

      image = cv2.imread('path/to/image')
      cc = cv2.CascadeClassifier('path/to/classifierfile')
      objs = cc.detectMultiScale(image)
      

      【讨论】: