OpenCV速度交通标志检测 [英] OpenCV speed traffic sign detection

查看:525
本文介绍了OpenCV速度交通标志检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Android的opencv 2.4来检测速度交通标志时遇到问题. 我执行以下操作:

捕获框->将其转换为HSV->提取红色区域->通过椭圆检测来检测符号"

到目前为止,只要图像质量良好,椭圆检测就可以完美运行. 但是,正如您在下面的图片中看到的那样,由于我认为相框质量较差,红色提取无法正常工作.

将原始图像转换为HSV:

Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3);

提取红色:

Core.inRange(this.source, new Scalar(this.h,this.s,this.v), new Scalar(230,180,180), this.source);

所以我的问题是还有另一种方法来检测这样的交通标志或从中提取红色区域吗,顺便说一句,就像上一张照片一样,这很微弱吗?

这是原始图像:

这会转换为HSV,因为您可以看到红色区域的颜色与附近树木的颜色相同.那就是我应该怎么知道它是红色的,但我不知道.

已转换为HSV:

这是提取的红色.如果颜色正确,我应该在符号周围得到几乎完美的圆形/椭圆形,但是由于颜色错误,该符号不完整.

提取后的结果:

椭圆方法:

private void findEllipses(Mat input){
Mat thresholdOutput = new Mat();
int thresh = 150;

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();

Imgproc.threshold(source, thresholdOutput, thresh, 255, Imgproc.THRESH_BINARY);
//Imgproc.Canny(source, thresholdOutput, 50, 180);
Imgproc.findContours(source, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
RotatedRect minEllipse[] = new RotatedRect[contours.size()];

for(int i=0; i<contours.size();i++){
    MatOfPoint2f temp=new MatOfPoint2f(contours.get(i).toArray());

    if(temp.size().height > minEllipseSize && temp.size().height < maxEllipseSize){
        double a = Imgproc.fitEllipse(temp).size.height;
        double b = Imgproc.fitEllipse(temp).size.width;
        if(Math.abs(a - b) < 10)
            minEllipse[i] = Imgproc.fitEllipse(temp);
    }
}
detectedObjects.clear();
for( int i = 0; i< contours.size(); i++ ){
    Scalar color = new Scalar(180, 255, 180);
    if(minEllipse[i] != null){
        detectedObjects.add(new DetectedObject(minEllipse[i].center));
        DetectedObject detectedObj = new DetectedObject(minEllipse[i].center);
        Core.ellipse(source, minEllipse[i], color, 2, 8);
    }
}

}

问题征兆:

解决方案

您可以找到交通标志检测方法的回顾 rrefer no

您将看到有两种方法可以实现此目的:

  1. 基于颜色(例如您现在正在做的事情)
  2. 基于形状

根据我的经验,我发现基于形状的方法效果很好,因为在不同的光照条件,相机质量等条件下,颜色可能会发生很大变化.

由于您需要检测速度交通标志(我认为该交通标志始终是圆形的),因此可以使用椭圆检测器在图像中找到所有圆形的对象,然后进行一些验证以确定是否为是否有交通标志.

为什么要检测椭圆?

好吧,既然您正在寻找透视扭曲的圆,那么实际上您正在寻找椭圆.实时椭圆检测是一个有趣的(尽管很有限)的研究主题.我将为您指出两篇提供C ++源代码的论文(您可以通过本机JNI调用在您的应用程序中使用它们):

  1. L. Libuda,I. Grothues,K.-F. Kraiss,数字图像中的椭圆检测 使用几何特征的数据,请参见:J.Braz,A.Ranchordas,H.Arajo, J. Jorge(编辑),计算机图形学和计算机视觉的进展, 《计算机与信息科学通讯》第4卷, Springer Berlin Heidelberg,2007年,第229-239页. 链接链接代码


更新

我尝试了方法2),没有进行任何预处理.您可以看到至少检测到带有红色边框的符号非常好:

I have a problem detecting speed traffic signs with opencv 2.4 for Android. I do the following:

"capture frame -> convert it to HSV -> extract red areas -> detect signs with ellipse detection"

So far ellipse detection works perfect as long as picture is good quality. But as you see in pictures bellow, that red extraction does not work OK, because of poor quality of picture frames, by my opinion.

Converting original image to HSV:

Imgproc.cvtColor(this.source, this.source, Imgproc.COLOR_RGB2HSV, 3);

Extracting red colors:

Core.inRange(this.source, new Scalar(this.h,this.s,this.v), new Scalar(230,180,180), this.source);

So my question is is there another way of detecting traffic sign like this or extracting red areas out of it, which by the way can be very faint like in last picture ?

This is the original image:

This is converted to HSV, as you can see red areas look the same color as nearby trees. Thats how I'm suppose to know it's red but I can't.

Converted to HSV:

This is with red colors extracted. If colors would be correct I should get almost perfect circle/ellipse around sign, but it is incomplet due to false colors.

Result after extraction:

Ellipse method:

private void findEllipses(Mat input){
Mat thresholdOutput = new Mat();
int thresh = 150;

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
MatOfInt4 hierarchy = new MatOfInt4();

Imgproc.threshold(source, thresholdOutput, thresh, 255, Imgproc.THRESH_BINARY);
//Imgproc.Canny(source, thresholdOutput, 50, 180);
Imgproc.findContours(source, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
RotatedRect minEllipse[] = new RotatedRect[contours.size()];

for(int i=0; i<contours.size();i++){
    MatOfPoint2f temp=new MatOfPoint2f(contours.get(i).toArray());

    if(temp.size().height > minEllipseSize && temp.size().height < maxEllipseSize){
        double a = Imgproc.fitEllipse(temp).size.height;
        double b = Imgproc.fitEllipse(temp).size.width;
        if(Math.abs(a - b) < 10)
            minEllipse[i] = Imgproc.fitEllipse(temp);
    }
}
detectedObjects.clear();
for( int i = 0; i< contours.size(); i++ ){
    Scalar color = new Scalar(180, 255, 180);
    if(minEllipse[i] != null){
        detectedObjects.add(new DetectedObject(minEllipse[i].center));
        DetectedObject detectedObj = new DetectedObject(minEllipse[i].center);
        Core.ellipse(source, minEllipse[i], color, 2, 8);
    }
}

}

Problematic sign:

解决方案

You can find a review of traffic signs detection methods here and here.

You'll see that there are 2 ways you can achieve this:

  1. Color-based (like what you're doing now)
  2. Shape-based

In my experience, I found that shape-based methods works pretty good, because the color may change a lot under different lighting conditions, camera quality, etc.

Since you need to detect speed traffic signs, which I assume are always circular, you can use an ellipse detector to find all circular objects in your image, and then apply some validation to determine if it's a traffic sign or not.

Why ellipse detection?

Well, since you're looking for perspective distorted circles, you are in fact looking for ellipses. Real-time ellipse detection is an interesting (although limited) research topic. I'll point you out to 2 papers with C++ source code available (which you can use in you app through native JNI calls):

  1. L. Libuda, I. Grothues, K.-F. Kraiss, Ellipse detection in digital image data using geometric features, in: J. Braz, A. Ranchordas, H. Arajo, J. Jorge (Eds.), Advances in Computer Graphics and Computer Vision, volume 4 of Communications in Computer and Information Science, Springer Berlin Heidelberg, 2007, pp. 229-239. link, code

  2. M. Fornaciari, A. Prati, R. Cucchiara, "A fast and effective ellipse detector for embedded vision applications", Pattern Recognition, 2014 link, code


UPDATE

I tried the method 2) without any preprocessing. You can see that at least the sign with the red border is detected very good:

这篇关于OpenCV速度交通标志检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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