首页 > 解决方案 > OpenCV edge based object detection C++

问题描述

I have an application where I have to detect the presence of some items in a scene. The items can be rotated and a little scaled (bigger or smaller). I've tried using keypoint detectors but they're not fast and accurate enough. So I've decided to first detect edges in the template and the search area, using Canny ( or a faster edge detection algo ), and then match the edges to find the position, orientation, and size of the match found.

All this needs to be done in less than a second.

I've tried using matchTemplate(), and matchShape() but the former is NOT scale and rotation invariant, and the latter doesn't work well with the actual images. Rotating the template image in order to match is also time consuming.

So far I have been able to detect the edges of the template but I don't know how to match them with the scene.

I've already gone through the following but wasn't able to get them to work (they're either using old version of OpenCV, or just not working with other images apart from those in the demo):

https://www.codeproject.com/Articles/99457/Edge-Based-Template-Matching

Angle and Scale Invariant template matching using OpenCV

https://answers.opencv.org/question/69738/object-detection-kinect-depth-images/

Can someone please suggest me an approach for this? Or a code snipped for the same if possible ?

This is my sample input image ( the parts to detect are marked in red )

Sample input image

These are some software that are doing this and also how I want it should be:

enter image description here

enter image description here

标签: c++opencvvisual-c++object-detectiontemplate-matching

解决方案


这个话题是我在一个项目上实际处理的一年。因此,我将尝试解释我的方法是什么以及我是如何做到的。我假设您已经完成了预处理步骤(滤镜、亮度、曝光、校准等)。并确保清除图像上的噪音。

注意:在我的方法中,我从参考图像上的轮廓收集数据,这是我想要的对象。然后我将这些数据与大图像上的其他轮廓进行比较。

  1. 使用精明的边缘检测并找到参考图像上的轮廓。你需要在这里确定它不应该错过轮廓的某些部分。如果它错过了,可能预处理部分应该有一些问题。另一个重要的一点是,您需要找到合适的findContours模式,因为每种模式都有不同的属性,因此您需要为您的情况找到合适的模式。最后,您需要消除适合您的轮廓。

  2. 从参考中获取轮廓后,您可以使用 findContours() 的 outputArray 找到每个轮廓的长度。您可以在大图像上比较这些值并消除如此不同的轮廓。

  3. minAreaRect为每个轮廓精确地绘制一个合适的封闭矩形。就我而言,这个功能非常好用。我使用此函数获得 2 个参数:

    a)计算拟合矩形的短边和长边,并将值与大图像上的其他轮廓进行比较。

    b)计算黑度或白度的百分比(如果您的图像是灰度的,则获得接近白色或黑色的像素的百分比)并在最后进行比较。

  4. matchShape可以在最后应用于其余轮廓,或者您也可以应用于所有轮廓(我建议第一种方法)。每个轮廓只是一个数组,因此您可以将参考轮廓保存在一个数组中,并在最后将它们与其他轮廓进行比较。完成 3 个步骤然后应用 matchShape 对我来说非常好。

  5. 我觉得matchTemplate不好直接用。我将每个轮廓绘制到不同的垫零图像(空白黑色表面)作为模板图像,然后与其他轮廓进行比较。直接使用参考模板图像不会产生好的结果。

  6. OpenCV 有一些关于寻找圆、凸度等的很好的算法。如果您的情况与它们有关,您也可以将它们用作一个步骤。

  7. 最后,您只需获取所有数据、值,您就可以在脑海中制作一个表格。剩下的就是统计分析。

注意:我认为最重要的部分是预处理部分。因此,请确保您拥有干净、几乎无噪音的图像和参考。

注意:如果您只想知道对象是否存在,培训可能是您的情况的一个很好的解决方案。但如果你想为工业应用做点什么,这是完全错误的方式。我多次尝试了 YOLO 和 haarcascade 训练算法,还用它们训练了一些对象。我得到的经验是:他们几乎可以正确找到物体,但即使您的校准正确,中心坐标、旋转结果等也不会完全正确。另一方面,训练时间和收集数据是痛苦的。


推荐阅读