基于 OpenCV 边缘的对象检测 C++ [英] OpenCV edge based object detection C++

查看:83
本文介绍了基于 OpenCV 边缘的对象检测 C++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,我必须在其中检测场景中某些项目的存在.这些项目可以旋转并稍微缩放(更大或更小).我试过使用关键点检测器,但它们不够快速和准确.所以我决定首先使用 Canny(或更快的边缘检测算法)检测模板和搜索区域中的边缘,然后匹配边缘以找到找到的匹配的位置、方向和大小.

所有这些都需要在不到一秒的时间内完成.

我尝试过使用 matchTemplate()matchShape() 但前者不是缩放和旋转不变的,而后者不适用于实际图像.旋转模板图片以进行匹配也很耗时.

到目前为止,我已经能够检测到模板的边缘,但我不知道如何将它们与场景匹配.

我已经完成了以下操作,但无法让它们工作(它们要么使用旧版本的 OpenCV,要么只是无法使用演示中的图像以外的其他图像):

<块引用>

这些是一些正在执行此操作的软件以及我希望它应该如何:

解决方案

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

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

  1. 使用canny边缘检测并在参考上找到轮廓图像.你需要在这里确定它不应该错过某些部分轮廓.如果它错过了,可能预处理部分应该有一些问题.另一个重要的点是你需要找到一个findContours 的适当模式,因为每个模式有不同的属性,所以你需要找到一个适合你的案件.最后,你需要消除那些很好的轮廓给你.

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

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

    a) 计算拟合矩形的短边和长边并比较大图像上其他轮廓的值.

    b) 计算黑度或白度的百分比(如果您的图像是灰度,获得接近白色或黑色的像素的百分比)和最后比较.

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

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

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

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

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

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

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 )

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

解决方案

This topic is what I am actually dealing for a year on a project. So I will try to explain what my approach is and how I am doing that. I assume that you already did the preprocess steps(filters,brightness,exposure,calibration etc). And be sure you clean the noises on image.

Note: In my approach, I am collecting data from contours on a reference image which is my desired object. Then I am comparing these data with the other contours on the big image.

  1. Use canny edge detection and find the contours on reference image. You need to be sure here about that it shouldn't miss some parts of contours. If it misses, probably preprocess part should have some problems. The other important point is that you need to find an appropriate mode of findContours because every modes have different properties so you need to find an appropriate one for your case. At the end you need to eliminate the contours which are okey for you.

  2. After getting contours from reference, you can find the length of every contours using outputArray of findContours(). You can compare these values on your big image and eliminate the contours which are so different.

  3. minAreaRect precisely draws a fitted, enclosing rectangle for each contour. In my case, this function is very good to use. I am getting 2 parameters using this function:

    a) Calculate the short and long edge of fitted rectangle and compare the values with the other contours on the big image.

    b) Calculate the percentage of blackness or whiteness(if your image is grayscale, get a percentage how many pixel close to white or black) and compare at the end.

  4. matchShape can be applied at the end to the rest of contours or you can also apply to all contours(I suggest first approach). Each contour is just an array so you can hold the reference contours in an array and compare them with the others at the end. After doing 3 steps and then applying matchShape is very good on my side.

  5. I think matchTemplate is not good to use directly. I am drawing every contour to a different mat zero image(blank black surface) as a template image and then I compare with the others. Using a reference template image directly doesnt give good results.

  6. OpenCV have some good algorithms about finding circles,convexity etc. If your situations are related with them, you can also use them as a step.

  7. At the end, you just get the all data,values, and you can make a table in your mind. The rest is kind of statistical analysis.

Note: I think the most important part is preprocess part. So be sure about that you have a clean almost noiseless image and reference.

Note: Training can be a good solution for your case if you just want to know the objects exist or not. But if you are trying to do something for an industrial application, this is totally wrong way. I tried YOLO and haarcascade training algorithms several times and also trained some objects with them. The experiences which I get is that: they can find objects almost correctly but the center coordinates, rotation results etc. will not be totally correct even if your calibration is correct. On the other hand, training time and collecting data is painful.

这篇关于基于 OpenCV 边缘的对象检测 C++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆