ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

基于ARM-Linux系统、Qt、OpenCV的红绿灯识别系统

2022-02-01 19:32:52  阅读:258  来源: 互联网

标签:src return Qt 红绿灯 Point yellow OpenCV green Linux


1.题目介绍

红绿灯识别一向是自动驾驶实现的难点,而且是不得不攻克的难点。三色识别固然简单,然而这三多干扰中找出红绿灯并进行识别是问题的关键。红绿灯识别算法主要利用了交通灯的色彩特征及形状特征。

2.工作原理

区域提取

由于红绿灯的形状大多为圆形,采用基于形状特征的检测方法,从复杂的场景中,找出图片中的圆形,再对图像进行滤波处理,只留下感兴趣区域。

颜色识别

将RGB色彩转换成HSV模型,通过红绿黄3 种颜色的HSV阈值不同,提取分割后的红绿灯图像中HSV三通道的值,判断图像中何种颜色的分量占据多数,即可判断出此刻红绿灯的状态。

3.核心代码

调整图片大小,锁定纵横比

//调整图片大小
String filename=FileName.toStdString();
 Mat src = imread(filename); 
if (src.empty()) 
{ 
	QMessageBox::information(this,"Information","Cannot open the picture"); 
	return -1;
 } 
int Rows=600; 
int Cols=src.cols*600/src.rows;
 Mat dst(Rows,Cols,src.type());
 cv::resize(src,dst,dst.size(),0,0,INTER_LINEAR);

区域提取

//霍夫变换圆检测

medianBlur(src, mout, 7); cvtColor(mout, mout, COLOR_BGR2GRAY); 
cvtColor(mout, mout, COLOR_BGR2GRAY);//转化为灰度图
HoughCircles(mout, circles, HOUGH_GRADIENT, 1, 10, 100, 30, 5, 25);

image:输入图像:8-bit,灰度图
circles:输出圆的结果。
method:定义检测图像中圆的方法。目前唯一实现的方法HOUGH_GRADIENT。
dp:寻找圆弧圆心的累计分辨率,这个参数允许创建一个比输入图像分辨率低的累加器。(这样做是因为有理由认为图像中存在的圆会自然降低到与图像宽高相同数量的范畴)。如果dp设置为1,则分辨率是相同的;如果设置为更大的值(比如2),累加器的分辨率受此影响会变小(此情况下为一半)。dp的值不能比1小。
minDist:该参数是让算法能明显区分的两个不同圆之间的最小距离。
param1 :用于Canny的边缘阀值上限,下限被置为上限的一半。
param2:HOUGH_GRADIENT方法的累加器阈值。阈值越小,检测到的圈子越多。
minRadius :最小圆半径。
maxRadius:最大圆半径
for (int i = 0;( i < circles.size())&&i<100; i++) {
        Vec3f c = circles[i];
        Point center(c[0], c[1]);
        int radius = c[2];
        Mat split_circle(src.rows, src.cols, src.type(), Scalar(0, 0, 0));
        int count = 0;
        for (int x = 0; x < src.cols; x++)
        {
            for (int y = 0; y < src.rows; y++)
            {
                int temp = ((x - center.x) * (x - center.x) + (y - center.y) * (y - center.y));
                if (temp < (radius * radius))
                {
                    split_circle.at<Vec3b>(Point(x, y))[0] = src.at<Vec3b>(Point(x, y))[0];
                    split_circle.at<Vec3b>(Point(x, y))[1] = src.at<Vec3b>(Point(x, y))[1];
                    split_circle.at<Vec3b>(Point(x, y))[2] = src.at<Vec3b>(Point(x, y))[2];
                    count++;
                }
                else
                {
                      split_circle[i].at<Vec3b>(Point(x, y))[0] = 0;
                      split_circle[i].at<Vec3b>(Point(x, y))[1] = 0;
                      split_circle[i].at<Vec3b>(Point(x, y))[2] = 0;
                }
            }
        }

颜色识别

//转化为hsv模型
    cvtColor(image, hsv, COLOR_BGR2HSV);
    if (total == 0)
    {
        return -1;
    }

//根据颜色阈值分别得到掩膜
    inRange(hsv, lower_green, upper_green, maskGreen);
    inRange(hsv, lower_red1, upper_red1, maskRed);
    inRange(hsv, lower_yellow, upper_yellow, maskYellow);
//用掩膜进行二值化处理,并统计识别出的像素数目
 
    medianBlur(maskGreen, green_result, 5);
    green = countNonZero(green_result);

   medianBlur(maskRed, red_result, 5);
    red = countNonZero(red_result);

   medianBlur(maskYellow, yellow_result, 5);
    yellow = countNonZero(yellow_result);

颜色判决

//颜色判决
 if ((yellow*1.0/total >= 0.5)|| (red*1.0 / total >=0.5 )||  (green*1.0 / total >= 0.5))
//判断红绿黄三色的像素占比是否过半
    {
        if (green > red && green > yellow) return 3;
        else if (red > yellow) return 2;
        else return 1;
    }
    else
    {
        return -1;//像素比例不够,退出函数
    }

在ARM开发板study210上的效果图,可以实现对包含红绿灯图片中的红绿灯进行识别,并输出在文本框上,以动画的形式显示在左边。

 源代码如下所示:

基于ARM-Linux系统、Qt、OpenCV的红绿灯识别系统源代码-Linux文档类资源-CSDN文库

 

标签:src,return,Qt,红绿灯,Point,yellow,OpenCV,green,Linux
来源: https://blog.csdn.net/where_are_u/article/details/122765355

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有