openCv +3.4.0 车牌定位(C++版本)

#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;

}

 

你可能感兴趣的:(机器视觉)