#include
#include
#include
#include
#include "opencv2/shape.hpp"
using namespace cv;
using namespace std;
//函数声明
Mat ReSize(Mat imgArr ,int maxWidth, int maxHeight);
Mat ImgProcess(Mat reSizeImg);
//vector > FindContour(Mat processImg);
int main() {
//创建窗口
//namedWindow("Car原画");
//namedWindow("Car灰度图");
//定义变量
Mat grayImg;
Mat img = imread("E:/OpenCv/CarDetect/Car.png");
int maxWindowWidth=400;
int maxWindowHeight=300;
cvtColor(img, grayImg, COLOR_BGR2GRAY);
//imshow("Car原画", img);
//imshow("Car灰度图", grayImg);
Mat grayImgResize= ReSize(grayImg, maxWindowWidth, maxWindowHeight);
imshow("CarReSize", grayImgResize);
Mat imgPro = ImgProcess(grayImgResize);
imshow("形态学处理", imgPro);
//vector > contourImg;
//contourImg = FindContour(imgPro);
//imshow("特征", contourImg);
// 等待6000 ms后窗口自动关闭
waitKey(0);
destroyAllWindows();
}
//这个函数的作用就是来调整图像的尺寸大小,当输入图像尺寸的宽度大于阈值(默认1000),我们会将图像按比例缩小
Mat ReSize(Mat imgArr,int maxWidth,int maxHeight) {
Mat imgReSize;
double changeXRate = 0.0;
double changeYRate = 0.0;
Size dsize =Size(maxWidth, maxHeight);
int width = imgArr.cols;
int height = imgArr.rows;
if (width > maxWidth) {
changeXRate = maxWidth / width;
}
resize(imgArr, imgReSize, dsize, changeXRate, changeYRate);
return imgReSize;
}
Mat ImgProcess(Mat reSizeImg) {
Mat imgPro;
Size kSize = Size(5,5);
Mat contourImg;
Mat thresholdImg;
Mat edgesImg;
Mat openingImg;
Mat closingImg;
//高斯滤波
Mat imgGauss;
GaussianBlur(reSizeImg, imgGauss, kSize, 0, 0, BORDER_DEFAULT);
Size mSize = Size(23, 23);
Point mPoint = Point(-1, -1);
Mat kernel = getStructuringElement(MORPH_RECT, mSize, mPoint);
Mat imgOpening;
morphologyEx(imgGauss, imgOpening, MORPH_OPEN, kernel, mPoint,2, BORDER_DEFAULT, morphologyDefaultBorderValue());
addWeighted(reSizeImg,1, imgOpening,-1,0, imgOpening,-1);
imshow("imgOpening", imgOpening);
// 找到图像边缘
threshold(imgOpening, thresholdImg, 0, 255, THRESH_BINARY + THRESH_OTSU);
imshow("thresholdImg", thresholdImg);
Canny(thresholdImg, edgesImg, 100, 200, 3, false);
imshow("edgesImg", edgesImg);
//使用开运算和闭运算让图像边缘成为一个整体
Size mSize1 = Size(7, 7);
Point mPoint1 = Point(-1, -1);
Mat kernel1 = getStructuringElement(MORPH_RECT, mSize1, mPoint1);
morphologyEx(edgesImg, closingImg, MORPH_CLOSE, kernel1, mPoint1, 2, BORDER_DEFAULT, morphologyDefaultBorderValue());
imshow("closingImg", closingImg);
Size mSize2 = Size(7, 7);
Mat kernel2 = getStructuringElement(MORPH_RECT, mSize2, mPoint1);
morphologyEx(closingImg, openingImg, MORPH_OPEN, kernel2, mPoint1, 2, BORDER_DEFAULT, morphologyDefaultBorderValue());
imshow("openingImg", openingImg);
//查找图像边缘整体形成的矩形区域,可能有很多,车牌就在其中一个矩形区域中
vector > contoursArrs;
vector hierarchy;
findContours(openingImg, contoursArrs, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
vector > tempContoursArrs(contoursArrs.size());
//contourArea(contoursArr, false);
int k = 0;
for (size_t i = 0; i < contoursArrs.size(); i++) {
if (contourArea(contoursArrs[i], false) > 2000) {
tempContoursArrs[k] = contoursArrs[i];
k++;
cout << contourArea(contoursArrs[i], false)< minRotatedRect(k);
vector minRect(k);
for (size_t i = 0; i < k; i++) {
minRotatedRect[i]=minAreaRect(tempContoursArrs[i]);
cout << minRotatedRect[i].size<< endl;
double ratio = minRotatedRect[i].size.height / minRotatedRect[i].size.width;
int m = 0;
//Mat drawing = Mat::zeros(openingImg.size(), CV_8UC3);
vector > PlateContoursArrs(k);
if ((ratio > 2.8 && ratio <2.9)) {
RNG rng(12345);
PlateContoursArrs[m] = tempContoursArrs[i];
vector plateRotatedRect(k);
plateRotatedRect [m]= minAreaRect(PlateContoursArrs[m]);
Scalar color = Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
// contour
drawContours(reSizeImg, PlateContoursArrs, (int)0, color);
// ellipse
//ellipse(drawing, minEllipse[i], color, 2);
// rotated rectangle
Point2f rect_points[4];
minRotatedRect[i].points(rect_points);
for (int j = 0; j < 4; j++)
{
line(reSizeImg, rect_points[j], rect_points[(j + 1) % 4], color);
}
imshow("ContoursLine", reSizeImg);
//提取图片
Rect brect = plateRotatedRect[m].boundingRect(); //返回包含旋转矩形的最小矩形
//rectangle(reSizeImg, brect, color, 1, 8, 0);
rectangle(reSizeImg, brect, Scalar(0, 0, 255));
imshow("RectImg'", reSizeImg);
m++;
}
}
imgPro = imgOpening;
return imgPro;
}