學習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);
}