交通标识检测c++代码实例及运行结果
2018-01-06 13:45
495 查看
环境vs2013+opencv2.4.9
交通标识分为检测和识别两部分,检测只检测红色标识,其他标识同理。本片博客介绍交通标识检测部分,识别部分后续介绍。
c++代码
运行结果
原始图
检测结果
交通标识分为检测和识别两部分,检测只检测红色标识,其他标识同理。本片博客介绍交通标识检测部分,识别部分后续介绍。
c++代码
#include<iostream> #include<opencv2/opencv.hpp> #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 = imread("result\\1.jpg"); //resize(srcImg, srcImg, Size(204.8, 137.6));重置图片大小为什么检测不到 imshow("srcImg",srcImg); Mat srcImgCopy; srcImg.copyTo(srcImgCopy); int width = srcImg.cols;//图像宽度 int height = srcImg.rows;//图像高度 double B = 0.0, G = 0.0, R = 0.0, H = 0.0, S = 0.0, V = 0.0; Mat matRgb = Mat::zeros(srcImg.size(), CV_8UC1); int x, y; //循环 for (y = 0; y<height; y++) { for (x = 0; x<width; x++) { // 获取BGR值 B = srcImg.at<Vec3b>(y, x)[0]; G = srcImg.at<Vec3b>(y, x)[1]; R = srcImg.at<Vec3b>(y, x)[2]; RGB2HSV(R, G, B, H, S, V); //红色范围 if ((H >= 337 && H <= 360 || H >= 0 && H <= 10) && S >= 12 && S <= 100 && V>20 && V<99) { matRgb.at<uchar>(y, x) = 255; } } } blur(matRgb, matRgb, Size(3, 3)); Mat element = getStructuringElement(MORPH_ELLIPSE, Size(2 * 1 + 1, 2 * 1 + 1), Point(1, 1)); Mat element1 = getStructuringElement(MORPH_ELLIPSE, Size(2 * 3 + 1, 2 * 3 + 1), Point(3, 3)); erode(matRgb, matRgb, element);//腐蚀 imshow("erode", matRgb); dilate(matRgb, matRgb, element1);//膨胀 imshow("dilate", matRgb); fillHole(matRgb, matRgb);//填充 imshow("fillHole", matRgb); Mat matRgbCopy; matRgb.copyTo(matRgbCopy); //cvtColor(srcImg, grayImg, CV_BGR2GRAY); vector<vector<Point>>contours; //轮廓 vector<Vec4i> hierarchy;//分层 findContours(matRgb, 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(matRgb.size(), CV_8UC3); //int count1 = 0; for (int i = 0; i < contours.size(); i++) { Rect rect = boundRect[i]; //首先进行一定的限制,筛选出区域 //高宽比限制 float ratio = (float)rect.width / (float)rect.height; //轮廓面积 float Area = (float)rect.width * (float)rect.height; float dConArea = (float)contourArea(contours[i]); float dConLen = (float)arcLength(contours[i], 1); if (dConArea < 400) continue; if (ratio > 2 || ratio < 0.5) continue; //进行圆筛选,通过四块的缺失像素比较 Mat roiImage; matRgbCopy(rect).copyTo(roiImage); Mat temp; srcImgCopy(rec b3e5 t).copyTo(temp); float C = (4 * PI*dConArea) / (dConLen*dConLen); if (C < 0.4)//利用圆度初步对形状进行筛选 continue; srcImgCopy(rect).copyTo(roiImage); Scalar color = (0, 0, 255);//蓝色线画轮廓 drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point()); rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); rectangle(srcImg, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); imshow("1_1.jpg", srcImg); imwrite("result\\1_1.jpg", srcImg);//保存最终的检测识别结果 } waitKey(0); //system("pause"); return 0; }
运行结果
原始图
检测结果
相关文章推荐
- 交通标识检测c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- Opencv检测交通中红色标识轮廓c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果
- 交通标识检测c++代码实例及运行结果