车牌识别代码OpenCV
#include<opencv2\opencv.hpp>
#include<iostream> using namespace cv; using namespace std; int areas;
//该函数用来验证是否是我们想要的区域,车牌定位原理其实就是在图片上寻找矩形,我们可以用长宽比例以及面积来验证是否是我们想要的矩形,宽高比为520/110=4.7272 (车牌的长除以宽),区域面积最小为15个像素,最大为125个像素
bool VerifySize(RotatedRect candidate) { float error = 0.4; //40%的误差范围
float aspect = 4.7272;//宽高比例
int min = 25 * aspect * 25; //最小像素为15
int max = 125 * aspect * 125;//最大像素为125
float rmin = aspect - aspect*error;//最小误差
float rmax = aspect + aspect*error;//最大误差
int area = candidate.size.height*candidate.size.width;//求面积
float r = (float)candidate.size.width / (float)candidate.size.height;//长宽比
if (r < 1)
r = 1 / r;
if (area<min || area>max || r<rmin || r>rmax)
return false;
else
return true; } int main(int argc, char** argv) {
Mat src;
src = imread("D:\\Car1.jpg");//读取含车牌的图片
if (!src.data) {
cout << "Could not open Car.jph.." << endl;
return -1;
}
Mat img_gray;
cvtColor(src, img_gray, CV_BGR2GRAY);//灰度转换
Mat img_blur;
blur(img_gray, img_blur, Size(5, 5));//用来降噪
Mat img_sobel;
Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3);//Sobel滤波,对x进行求导,就是强调y方向,对y进行求导,就是强调x方向,在此我们对x求导,查找图片中的竖直边
Mat img_threshold;
threshold(img_sobel, img_threshold, 0, 255, THRESH_BINARY | THRESH_OTSU);
Mat element = getStructuringElement(MORPH_RECT, Size(21, 5));//这个Size很重要!!不同的图片适应不同的Size,待会在下面放图,大家就知道区别了
morphologyEx(img_threshold, img_threshold,MORPH_CLOSE,element);//闭操作,就是先膨胀后腐蚀,目的就是将图片联通起来,取决于element的Size
。 /*接下来就是提取轮廓*/
vector<vector<Point>>contours;
findContours(img_threshold, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
Mat result = Mat::zeros(src.size(), CV_8U);
drawContours(result, contours, -1, Scalar(255));
vector<RotatedRect> rects; //用来存放旋转矩形的容器
//Mat result1 = Mat::zeros(src.size(), CV_8U);
Mat result1;
src.copyTo(result1);
for (size_t i = 0; i < contours.size(); i++) {
Point2f vertices[4];//用来存放旋转矩形的四个点
RotatedRect mr = minAreaRect(Mat(contours[i]));
//minAreaRect 寻找最小的矩形
if (VerifySize(mr))//筛选是否是我们需要的区域,如果验证成功,就放到rects里,
{
//if (mr.angle > -30) {
mr.points(vertices);
for (size_t j = 0; j < 4; j++)
{
line(result1, vertices[j], vertices[(j + 1) % 4], Scalar(0, 0, 255), 2, 8);
cout << "矩形坐标"<<j<<"为" << vertices[j] << endl;
}
cout << "height:" << mr.size.height << endl << "weight:" << mr.size.width << endl;
rects.push_back(mr);
cout << "矩形角度:" << mr.angle << endl; // }
}
}
vector<Mat>output;//用于存放识别到的图像
for (size_t i = 0; i < rects.size(); i++)
{
Mat dst_warp;
Mat dst_warp_rotate;
Mat rotMat(2, 3, CV_32FC1);
dst_warp = Mat::zeros(src.size(), src.type());
float r = (float)rects[i].size.width / (float)rects[i].size.height;
float angle = rects[i].angle;
if (r < 1)
angle = angle + 90;
rotMat = getRotationMatrix2D(rects[i].center,angle, 1);//其中的angle参数,正值表示逆时针旋转,关于旋转矩形的角度,以为哪个是长哪个是宽,在下面会说到
warpAffine(src, dst_warp_rotate, rotMat, dst_warp.size());//将矩形修正回来
Size rect_size = rects[i].size;
if (r < 1)
swap(rect_size.width, rect_size.height);
Mat dst(rects[i].size, CV_8U);
getRectSubPix(dst_warp_rotate, rect_size, rects[i].center, dst);//裁剪矩形
/*以下代码是将裁减到的矩形设置为相同大小,并且提高对比度*/
Mat resultResized;
resultResized.create(33, 144, CV_8UC3);
resize(dst, resultResized, resultResized.size(), 0, 0, INTER_CUBIC);
Mat grayResult;
cvtColor(resultResized, grayResult, CV_BGR2GRAY);
blur(grayResult, grayResult, Size(3, 3));
equalizeHist(grayResult, grayResult); //均值化提高对比度
output.push_back(grayResult); //存放图片
}
char name[20] = "";
for (size_t i = 0; i < output.size(); i++)
{
if(i==0){
imwrite("D:\\CCar.jpg",output[0]);
sprintf_s(name, "识别到的第%d个车牌", i+1);
imshow(name, output[i]);
}
}
waitKey(0);
return 0;
}
#include <iostream> #include <opencv2/opencv.hpp>
using namespace std; using namespace cv;
int main(){
Mat img = imread("D:\\CCar.jpg",1);
/* 第一个参数是图片的绝对地址 第二个参数表示图片读入的方式(flags可以缺省,缺省时flags=1,表示以彩色图片方式读入图片) flags>0时表示以彩色方式读入图片 flags=0时表示以灰度图方式读入图片 flags<0时表示以图片的本来的格式读入图片 */
imshow("123", img);
//“123”是显示框的名字
int a = waitKey(10000);
//通过整型变量a获取waitKey函数的返回值
cout << a << endl;
/* waitKey(x) 表示等x毫秒,在这期间如果有按键按下,则返回按键的ascii码,等待结束则会返回-1. 如果x=0,那么无限等待下去,直到有按键按下 !!!另外,在imshow之后如果没有waitKey语句则不会正常显示图像。即imshow不会生效!!!
*/
//estroyAllWindows();
//销毁窗口
Rect rect1(5,0,17,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut1 = Mat(img, rect1);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy1 = image_cut1.clone();
//clone函数创建新的图片
imshow("1",image_copy1);
waitKey();
imwrite( "D:\\Bar1.jpg", image_copy1);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
Rect rect2(23,0,16,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut2 = Mat(img, rect2);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy2 = image_cut2.clone();
//clone函数创建新的图片
imshow("2",image_copy2);
waitKey();
imwrite( "D:\\Bar2.jpg", image_copy2);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
Rect rect3(45,0,18,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut3 = Mat(img, rect3);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy3 = image_cut3.clone();
//clone函数创建新的图片
imshow("3",image_copy3); waitKey();
imwrite( "D:\\Bar3.jpg", image_copy3);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
Rect rect4(63,0,16,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut4 = Mat(img, rect4);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy4 = image_cut4.clone();
//clone函数创建新的图片
imshow("4",image_copy4);
waitKey();
imwrite( "D:\\Bar4.jpg", image_copy4);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
Rect rect5(79,0,16,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut5 = Mat(img, rect5);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy5 = image_cut5.clone();
//clone函数创建新的图片
imshow("5",image_copy5);
waitKey();
imwrite( "D:\\Bar5.jpg", image_copy5);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
Rect rect6(95,0,16,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut6 = Mat(img, rect6);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy6 = image_cut6.clone();
//clone函数创建新的图片
imshow("6",image_copy6);
waitKey();
imwrite( "D:\\Bar6.jpg", image_copy6);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
Rect rect7(111,0,16,27);
//创建一个Rect框,属于cv中的类,四个参数代表x,y,width,height
Mat image_cut7 = Mat(img, rect7);
//从img中按照rect进行切割,此时修改image_cut时image中对应部分也会修改,因此需要copy
Mat image_copy7 = image_cut7.clone();
//clone函数创建新的图片 imshow("7",image_copy7);
waitKey();
imwrite( "D:\\Bar7.jpg", image_copy7);
//保存mat格式的图片成jpg格式,或者png,bmp格式,文件大小依次递增
return 0;
}
车牌识别代码OpenCV的更多相关文章
- 《zw版·Halcon-delphi系列原创教程》简单的令人发指,只有10行代码的车牌识别脚本
<zw版·Halcon-delphi系列原创教程>简单的令人发指,只有10行代码的车牌识别脚本 简单的令人发指,只有10行代码的车牌识别脚本 人脸识别.车牌识别是opencv当中 ...
- 《Mastering Opencv ...读书笔记系列》车牌识别(II)
http://blog.csdn.net/jinshengtao/article/details/17954427 <Mastering Opencv ...读书笔记系列>车牌识别(I ...
- 《Mastering Opencv ...读书笔记系列》车牌识别(I)
http://blog.csdn.net/jinshengtao/article/details/17883075/ <Mastering Opencv ...读书笔记系列>车牌识别(I ...
- 基于opencv的车牌识别系统
前言 学习了很长一段时间了,需要沉淀下,而最好的办法就是做一个东西来应用学习的东西,同时也是一个学习的过程. 概述 OpenCV的全称是:Open Source Computer Vision ...
- opencv 视觉项目学习笔记(二): 基于 svm 和 knn 车牌识别
车牌识别的属于常见的 模式识别 ,其基本流程为下面三个步骤: 1) 分割: 检测并检测图像中感兴趣区域: 2)特征提取: 对字符图像集中的每个部分进行提取: 3)分类: 判断图像快是不是车牌或者 每个 ...
- opencv颜色识别代码分享
android 平台 opencv 实现颜色识别代码:http://www.eyesourcecode.com/thread-40682-1-1.htmlopencv的颜色识别简单实现的代码:http ...
- 毕业设计 python opencv实现车牌识别 界面
主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuow ...
- EasyPR--一个开源的中文车牌识别系统
我正在做一个开源的中文车牌识别系统,Git地址为:https://github.com/liuruoze/EasyPR. 我给它取的名字为EasyPR,也就是Easy to do Plate Reco ...
- 车牌识别LPR(三)-- LPR系统整体结构
第三篇:系统的整体架构 LPR系统大体上可由图像采集系统,图像处理系统,数据库管理系统三个子系统组成.它综合了通讯.信息.控制.传感.计算机等各种先进技术,构成一个智能电子系统. 图像采集系统:图像采 ...
随机推荐
- P1338 末日的传说,P1372 P1414 又是毕业季——贪心
一个1到n序列,合理排序逆序对数要求是m,而且字典序要求最小: 这个题,因为数字只能用一次,所以我们可以知道什么位置放什么数逆序对的个数会增加或减少多少: 先求出最多能产生的数量,每次先输出最小的数, ...
- 函数第二部分:为什么说动态参数是没有计划好的参数-Python基础前传(11)
动态参数1-一个星号变元组 动态参数存在的意义? 函数的作者有时候也不知道这个函数到底需要多少个参数,这时候动态参数就有存在的意义了 动态参数创建-加* 底层原理是:把数值型或其他数据类型变成了元组类 ...
- filter方法求出列表所有奇数并构造新列
a = [, , , , , , , , , ] b = filter(lambda x: x % != , a) for i in b: print(i)
- python pillow 绘制图片
demo1 #coding=utf- from PIL import Image img = Image.,))###创建一个5*5的图片 pixTuple = (,,,)###三个参数依次为R,G, ...
- $.extend和$.fn.extend详解
一.定义 $.extend()属于j全局的Query对象,用于将一个或多个对象合并到目标对象上: $.fn.extend()属于jQuery的原型对象,用于在jQuery原型上扩展实例属性和方法. 二 ...
- Apache Flink - Window
Window: 在Streaming中,数据是无限且连续的,我们不可能等所有数据都到才进行处理,我们可以来一个就处理一下,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们 ...
- WebSocketSharp 创建客户端和服务端
这里没有对onOpen.onClose.onError做案例,生产环境需要具备. 1.客户端 只推送不接收数据 创建WebSocketClient类 class WebSocketClient { W ...
- JMeter_控制器执行效果_给自己挖过的坑
线程及循环设置: 数据文件中放在“循环控制器”中的执行效果:每条数据执行5次,取够50条数据时停止 简单逻辑控制器按下面的目录创建后,执行结果效果同上面循环控制器的执行效果 本来想规整下目录结构,结果 ...
- linux工程管理软件—make
一.make概述 make是一种代码维护工具make工具会根据makefile文件定义的规则和步骤,完成整个软件项目的代码维护工作.一般用来简化编译工作,可以极大地提高软件开发的效率. win ...
- OpenJudge计算概论-苹果和虫子
/*======================================================== 苹果和虫子 总时间限制: 1000ms 内存限制: 65536kB 描述 你买了一 ...