Opencv實戰-交通標誌的識別

學習Opencv的API也有一段時間了
那麼我們是時候進行一些實戰教程了

左轉:接下來要做的就是識別交通標誌**

右轉:

在這裏插入圖片描述

有什麼思路可以區分左轉右轉呢

下面就是我的思路
1、用查找輪廓,並且畫出輪廓的矩形框
2、得出的矩形框,用ROI提取出來
3、得到的ROI再次查找輪廓,並且查找內層輪廓的凸包
4、凸包會得到輪廓二維點集
5、取二維點集的x軸數值
6、x軸數值的最小(及最左邊的x軸數值)和x軸數值的最大(及最右邊的的x軸數值)分別到兩邊框距離的比較,有箭頭的那一邊裏邊框的距離會比另一邊離框的距離小

在這裏插入圖片描述
這個比較就是區分的關鍵
上波代碼

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>    //Opencv highgui 模塊
#include <opencv2/imgproc/imgproc.hpp>    //Opencv 圖像處理頭文件
/******
*
*@戴鑫偉
*
* *****/
using namespace cv;
using namespace std;

void processFrame(Mat &mask, Rect &rect);
void detect_color();

Mat C_imHSV;     //HSV空間
Mat C_filter;    //顏色過濾
Mat C_expand;    //膨脹
Mat C_imgopen;   //開操作

Rect roi;
Mat imageROI;
Mat frame;
Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat element1 = getStructuringElement(MORPH_RECT, Size(10, 10));
Mat frame1;
int main()
{
	frame = imread("D:/opencv/opencvSRC/左轉3.jpg");
	imshow("原始圖", frame);
	detect_color();
	Mat h_imhsv;
	Mat ROI = frame(roi);
	Mat h_filter;
	//imshow("ROI", ROI);
	cvtColor(ROI, h_imhsv, COLOR_BGR2HSV);
	inRange(h_imhsv, Scalar(80, 70, 46), Scalar(124, 255, 255), h_filter);
	imshow("ROI過濾", h_filter);
	vector<vector<Point>> contours1;
	vector<Vec4i> hireachy1;
	Rect temprect1;
	findContours(h_filter, contours1, hireachy1, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
	vector<vector<Point> >hull(contours1.size());
	for (unsigned int i = 0; i < contours1.size(); i++)
	{
		convexHull(Mat(contours1[1]), hull[i]);
	}
	int max= hull[0][0].x;
	int min= hull[0][0].x;
	for (int j = 0; j < 10; j++)
	{
		
		if (max < hull[0][j].x)
		{
			max = hull[0][j].x;
		}
		if (min > hull[0][j].x)
		{
			min = hull[0][j].x;
		}
	}
	//cout << "max=" << max << endl;
	//cout << "min=" << min << endl;
	int rL;
	int lL;
	rL = h_filter.cols - max;
	lL = min;
	if (rL < lL)
	{
		printf("右轉");
	}
	else
	{
		printf("左轉");
	}
	Mat drawing = Mat::zeros(h_filter.size(), CV_8UC3);
	for (unsigned int i = 0; i < contours1.size(); i++)
	{
		Scalar color = Scalar(0,0,255);
		//drawContours(drawing, contours1, i, color, 1, 8, vector<Vec4i>(), 0, Point());
		drawContours(drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point());
	}

	imshow("效果圖", drawing);

	waitKey();
    return 0;
}

void processFrame(Mat &mask, Rect &rect)     //尋找輪廓
{
	vector<vector<Point>> contours;
	vector<Vec4i> hireachy;
	Rect temprect;
	findContours(mask, contours, hireachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
	if (contours.size() > 0)
	{
		double maxArea = 0.0;
		for (size_t t = 0; t < contours.size(); t++)
		{
			double area = contourArea(contours[static_cast<int>(t)]);
			if (area > maxArea)
			{
				maxArea = area;
				temprect = boundingRect(contours[static_cast<int>(t)]);
				if (temprect.height > 10 && temprect.width > 10)   //消除尋找到噪點的輪廓
				{
					rect = temprect;
				}
				else
				{
					rect.x = rect.y = rect.width = rect.height = 0;
				}
			}
		}
	}
	else
	{
		rect.x = rect.y = rect.width = rect.height = 0;
	}
}

void detect_color()
{
	//BGR轉HSV
	cvtColor(frame, C_imHSV, COLOR_BGR2HSV);
	//顏色過濾
	inRange(C_imHSV, Scalar(80, 70, 46), Scalar(124, 255, 255), C_filter);
	//開操作
	morphologyEx(C_filter, C_imgopen, MORPH_OPEN, element1);
	//膨脹
	dilate(C_imgopen, C_expand, element);
	//imshow("膨脹", C_expand);
	//找輪廓
	processFrame(C_expand, roi);
	rectangle(frame, roi, Scalar(0, 0, 255), 3, 8, 0);
	//imshow("找輪廓", frame);

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章