您的位置:首页 > 编程语言 > C语言/C++

Opencv检测交通中红色标识轮廓c++代码实例及运行结果

2018-01-05 22:27 621 查看
环境vs2013+opencv2.4.9

c++代码

#include<opencv2/opencv.hpp>
#include<iostream>
#define PI 3.1415926

using namespace std;
using namespace cv;

void RGB2HSV(double red, double green, double blue, double& hue, double& saturation, double& intensity)
{

double r, g, b;
double h, s, i;

double sum;
double minRGB, maxRGB;
double theta;

r = red / 255.0;
g = green / 255.0;
b = blue / 255.0;

minRGB = ((r<g) ? (r) : (g));
minRGB = (minRGB<b) ? (minRGB) : (b);

maxRGB = ((r>g) ? (r) : (g));
maxRGB = (maxRGB>b) ? (maxRGB) : (b);

sum = r + g + b;
i = sum / 3.0;

if (i<0.001 || maxRGB - minRGB<0.001)
{
h = 0.0;
s = 0.0;
}
else
{
s = 1.0 - 3.0*minRGB / sum;
theta = sqrt((r - g)*(r - g) + (r - b)*(g - b));
theta = acos((r - g + r - b)*0.5 / theta);
if (b <= g)
h = theta;
else
h = 2 * PI - theta;
if (s <= 0.01)
h = 0;
}

hue = (int)(h * 180 / PI);
saturation = (int)(s * 100);
intensity = (int)(i * 100);
}

void fillHole(const Mat srcBw, Mat &dstBw)
{
Size m_Size = srcBw.size();
Mat Temp = Mat::zeros(m_Size.height + 2, m_Size.width + 2, srcBw.type());//延展图像
srcBw.copyTo(Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)));

cv::floodFill(Temp, Point(0, 0), Scalar(255));//填充区域

Mat cutImg;//裁剪延展的图像
Temp(Range(1, m_Size.height + 1), Range(1, m_Size.width + 1)).copyTo(cutImg);

dstBw = srcBw | (~cutImg);
}

int main()
{
Mat srcImg;
srcImg = imread("1.jpg");//读取文件
resize(srcImg,srcImg,Size(200,200));//重定义图片大小
imshow("srcImg", srcImg);
int width = srcImg.cols;
int height = srcImg.rows;
/*
vector<Mat> hsv_vec;
Mat H, S, V;
cvtColor(srcImg, hsvImg, CV_BGR2HSV);
split(hsvImg, hsv_vec);
H = hsv_vec[0];
S = hsv_vec[1];
V = hsv_vec[2];
H.convertTo(H, CV_32F);
S.convertTo(S, CV_32F);
V.convertTo(V, CV_32F);
if ((H >= 337 && H <= 360 || H >= 0 && H <= 10))
*/
int x, y;
double B = 0.0, G = 0.0, R = 0.0, H = 0.0, S = 0.0, V = 0.0;
Mat vec_rgb = Mat::zeros(srcImg.size(), CV_8UC1);
for (x = 0; x < height; x++)
{
for (y = 0; y < width; y++)
{
B = srcImg.at<Vec3b>(x, y)[0];
G = srcImg.at<Vec3b>(x, y)[1];
R = srcImg.at<Vec3b>(x, y)[2];
RGB2HSV(R, G, B, H, S, V);
//红色范围,范围参考的网上。可以自己调
if ((H >= 312 && H <= 360 || H >= 0 && H <= 20) && (S >= 17 && S <= 100) && (V>18 && V < 100))
vec_rgb.at<uchar>(x, y) = 255;
}
}
imshow("hsv", vec_rgb);
medianBlur(vec_rgb, vec_rgb, 3);//中值滤波
imshow("medianBlur", vec_rgb);
Mat element = getStructuringElement(MORPH_ELLIPSE,Size(2*1+1,2*1+1),P
4000
oint(1,1));
Mat element1 = getStructuringElement(MORPH_ELLIPSE, Size(2 * 3 + 1, 2 * 3 + 1), Point(3, 3));
erode(vec_rgb, vec_rgb, element);//腐蚀
imshow("erode", vec_rgb);
dilate(vec_rgb, vec_rgb, element1);//膨胀
imshow("dilate", vec_rgb);
fillHole(vec_rgb, vec_rgb);//填充
imshow("fillHole", vec_rgb);
//cvtColor(srcImg, grayImg, CV_BGR2GRAY);
vector<vector<Point>>contours; //轮廓
vector<Vec4i> hierarchy;//分层
findContours(vec_rgb, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));//寻找轮廓
vector<vector<Point>> contours_poly(contours.size());  //近似后的轮廓点集
vector<Rect> boundRect(contours.size());  //包围点集的最小矩形vector
vector<Point2f> center(contours.size());  //包围点集的最小圆形vector
vector<float> radius(contours.size());  //包围点集的最小圆形半径vector
for (int i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); //对多边形曲线做适当近似,contours_poly[i]是输出的近似点集
boundRect[i] = boundingRect(Mat(contours_poly[i])); //计算并返回包围轮廓点集的最小矩形
minEnclosingCircle(contours_poly[i], center[i], radius[i]);//计算并返回包围轮廓点集的最小圆形及其半径
}

Mat drawing = Mat::zeros(vec_rgb.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = (0, 0, 255);//蓝色线画轮廓
drawContours(drawing, contours_poly, i, color, 1, 8, hierarchy, 0, Point());//根据轮廓点集contours_poly和轮廓结构hierarchy画出轮廓
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);//画矩形,tl矩形左上角,br右上角
circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);                                        //画圆形
}
/// 显示在一个窗口
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
imshow("Contours", drawing);

//system("pause");
waitKey();
return 0;
}


运行结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: