OpenCV3车牌识别(C++版)

您所在的位置:网站首页 视频车牌怎么用 OpenCV3车牌识别(C++版)

OpenCV3车牌识别(C++版)

2023-12-05 04:15| 来源: 网络整理| 查看: 265

车牌识别(基于OpenCV3.4.7+VS2017)

 

视频识别

 

蓝色车牌识别

    视觉入坑的第一个Demo(注释很详细),因为本人之前拖延,一直没能写详细实现博客,先将代码贴出来供大家交流,个人认为精华部分在字符切割(直接用指针遍历像素加限制条件切割),车牌模板已上传,整个工程也已上传,后续完善各环节实现步骤详解。  

头文件:Global.h

#ifdef GLOBAL extern int flag_1; extern bool flag; extern bool specialFlag; extern int captureRead extern string carPlate; extern char test[10]; extern struct stu1 { char number; Mat image; double matchDegree; }; extern struct stu { Mat image; double matchDegree; }; #endif

 

唯一的.cpp文件:PlateIdentify.cpp(说实话,这Demo挺 “C” 的)

 

#include #include #include #include"Global.h" #include #include using namespace std; using namespace cv; void fillHole(const Mat srcBw, Mat &dstBw); //填补算法 Mat cutOne(Mat cutImage); //边框切割算法 void CharCut(Mat srcImage); //单个字符切割算法 Mat Location(Mat srcImage); //图像识别算法 void SingleCharCut(Mat doubleImage, int k1, int k2); void ShowChar(); void MatchProvince(); void MatchNumber(); void readProvince(); void readNumber(); void VideoShow(Mat videoImage); void GetStringSize(HDC hDC, const char* str, int* w, int* h); void putTextZH(Mat &dst, const char* str, Point org, Scalar color, int fontSize, const char* fn, bool italic, bool underline); int flag_1; //判断是否倾斜,需不需要二次定位车牌 bool flag; //判断提取是否成功 bool specialFlag = false; //针对嵌套车牌 int captureRead = 0; int videoFlag = 0; string carPlateProvince = " "; string carPlate = " "; char test[10]; vector singleChar; //字符图片容器 int main(int argc, char *argv[]) { //计时开始 double time0 = static_cast(getTickCount()); //视频操作 VideoCapture capture("1.mp4"); Mat srcImage; Mat theFirst; int singleCharLength; //读取字符图片 readProvince(); readNumber(); while (1) { capture >> srcImage; try { if (!srcImage.data) { printf("视频识别结束 \n"); return 0; } if (srcImage.rows >= srcImage.cols) { resize(srcImage, srcImage, Size(640, 640 * srcImage.rows / srcImage.cols)); } else { resize(srcImage, srcImage, Size(400 * srcImage.cols / srcImage.rows, 400)); } //车牌定位 theFirst = Location(srcImage); if (flag) { if (flag_1 == 1) //旋转后要再次定位去上下杂边 { theFirst = Location(theFirst); flag_1 = 0; } } if (flag) { //车牌切割(切割上下边,去除干扰) theFirst = cutOne(theFirst); //单个字符切割 CharCut(theFirst); singleCharLength = singleChar.size(); printf("采取字符轮廓数 %d\n", singleCharLength); ShowChar(); if (singleCharLength >= 7) { MatchProvince(); MatchNumber(); } singleChar.clear(); } } catch (Exception e) { cout //判断变量重赋值 flag = false; //用于旋转车牌 int imageWidth, imageHeight; //输入图像的长和宽 imageWidth = srcImage.rows; //获取图片的宽 imageHeight = srcImage.cols; //获取图像的长 //!!!!!!!!!!!!!!!!!!! Mat blueROI = srcImage.clone(); cvtColor(blueROI, blueROI, CV_BGR2HSV); //namedWindow("hsv图"); //imshow("hsv图", blueROI); //中值滤波操作 medianBlur(blueROI, blueROI, 3); //namedWindow("medianBlur图"); //imshow("medianBlur图", blueROI); //将蓝色区域二值化 inRange(blueROI, Scalar(100, 130, 50), Scalar(124, 255, 255), blueROI); //namedWindow("blue图"); //imshow("blue图", blueROI); Mat element1 = getStructuringElement(MORPH_RECT, Size(2, 2)); //size()对速度有影响 morphologyEx(blueROI, blueROI, MORPH_OPEN, element1); //namedWindow("0次K运算后图像"); //imshow("0次K运算后图像", blueROI); Mat element0 = getStructuringElement(MORPH_ELLIPSE, Size(10, 10)); //size()对速度有影响 morphologyEx(blueROI, blueROI, MORPH_CLOSE, element0); //namedWindow("0次闭运算后图像"); //imshow("0次闭运算后图像", blueROI); vector contours; findContours(blueROI, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); int cnt = contours.size(); cout cout rect = boundingRect(contours[i]); //计算矩形边界 box = minAreaRect(contours[i]); //获取轮廓的矩形 box.points(vertex); //获取矩形四个顶点坐标 angle = box.angle; //得到车牌倾斜角度 longside = sqrt(pow(vertex[1].x - vertex[0].x, 2) + pow(vertex[1].y - vertex[0].y, 2)); shortside = sqrt(pow(vertex[2].x - vertex[1].x, 2) + pow(vertex[2].y - vertex[1].y, 2)); if (shortside > longside) //短轴大于长轴,交换数据 { temp = longside; longside = shortside; shortside = temp; cout printf("提取成功\n"); /*namedWindow("提取车牌结果图"); imshow("提取车牌结果图", image); */ //显示最终结果图 VideoShow(image); } rgbCutImg = srcImage(rect); //namedWindow("车牌图"); //imshow("车牌图", rgbCutImg);//裁剪出车牌 break; //退出循环,以免容器中变量变换 } } } cout printf("提取失败\n"); //后期加边缘检测法识别 if (!flag_1) //在视频中显示 { /*namedWindow("提取车牌结果图"); imshow("提取车牌结果图", image); */ //显示最终结果图 VideoShow(image); } } return rgbCutImg; } Mat cutOne(Mat cutImage) { //打印车牌长宽 try { /*cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3