基于SpringBoot+OpenCV+Maven开发的车票识别系统
项目介绍💁🏻
介绍:这是一个基于spring boot + maven + opencv 实现的图像识别及训练的Demo项目
包含车牌识别、人脸识别等功能,贯穿样本处理、模型训练、图像处理、对象检测、对象识别等技术点
包含功能
蓝、绿、黄车牌检测及车牌号码识别
网上常见的轮廓提取车牌算法JAVA实现
hsv色彩分割提取车牌算法JAVA实现
基于svm算法的车牌检测训练JAVA实现
基于ann算法的车牌号码识别训练JAVA实现
人脸检测 接下来将实现人脸识别
图片处理工具,目前实现了HSV色彩切割,后续将添加更多使用的图片处理工具,用于辅助算法优化
功能模块
车牌识别
图片工具
色相提取
色块校准
人脸识别
参与训练
软件版本
jdk 1.8.61+
maven 3.0+
opencv 4.0.1 ;javacpp1.4.4;opencv-platform 4.0.1-1.4.4
spring boot 2.1.5.RELEASE
yx-image-recognition 1.0.0版本
软件架构
B/S 架构,前端html + requireJS,后端java
数据库使用 sqlite3.0
接口文档使用swagger 2.0
页面效果
系统的部分功能模块页面如下所示。
部分实现代码效果
车牌识别过程说明文档
整体流程主要分两个大的步骤:
1、使用多种算法,提取到车牌的轮廓,按轮廓从原图片获取车牌的切图,使用SVM算法模型,判断该切图是否是车牌
2、根据车牌切图,判定车牌颜色,同时使用轮廓提取算法,提取车牌字符轮廓,按轮廓从二值图片获取车牌切图;使用ANN算法模型,分别使用中文字符模型、蓝牌模型、绿牌模型识别字符切图的文字内容
在进行学习相关知识的时候,至少要了解相关的图像二值化相关的处理操作,在进行学习的时候还要学习滤波相关的操作,在进行相关的处理以及对应的功能的时候,需要对模型进行训练才可以。
OpenCV 中,图像可以分别为1,2,3,4 通道
1 通道为灰度图;
2 通道的图像是RGB555和RGB565。2通道图在程序处理中会用到,如傅里叶变换,可能会用到,一个通道为实数,一个通道为虚数,主要是编程方便。RGB555是16位的,2个字节,5+6+5,第一字节的前5位是R,后三位+第二字节是G,第二字节后5位是B,可见对原图像进行压缩了
3 通道为彩色图(RGB);
4 通道为 RGBA ,是RGB加上一个A通道,也叫alpha通道,表示透明度,PNG图像是一种典型的4通道图像。alpha通道可以赋值0到1,或者0到255,表示透明到不透明
CvType 类型常量组合规则
byte : 比特数,位数。有 8byte,16byte,32byte,64byte;对应在Mat中,每个像素的所占的空间大小,8位即 CV_8
U|S|F :
U : unsigned int , 无符号整形
S : signed int , 有符号整形
F : float , 单精度浮点型, float类型本身即有符号 这里的有符号、无符号是针对图像二进制编码来讲的。我在写的过程中大多数情况下都是使用的无符号,即 CV_8U ,CV_16U,当有计算时
C[channels]:图像的通道数
比如 CV_8UC3 即 8位无符号的3通道(RGB 彩色)图像
灰度图像
彩色图像通常包括R、G、B三个分量,灰度化就是使彩色图像的R、G、B三个分量相等的过程
灰度图像中每个像素仅具有一种样本颜色,其灰度是位于黑色与白色之间的多级色彩深度,
灰度值大的像素点比较亮,反之比较暗,像素值最大为255(表示白色),像素值最小为0(表示黑色)
Imgproc.cvtColor(inMat, dst, Imgproc.COLOR_BGR2GRAY);
图像滤波(降噪)
图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性
目的有两类:一类是模糊;另一类是消除噪音
高斯滤波
也叫高斯模糊,模糊原理:
拿一个矩阵(3X3, 5X5)等,和原图从左向右从上到下分别进行卷积,将卷积值最后赋值个当前卷积的中心像素
矩阵的大小和矩阵的值,通常称矩阵为卷积核
用于 抑制噪声,平滑图像,防止把噪点也检测为边缘
高斯滤波相比于均值滤波对图像个模糊程度较小
public static final int BLUR_KERNEL = 3; // 滤波内核大小必须是 正奇数
public static void gaussianBlur(Mat inMat, Mat dst) {
Size ksize = new Size(BLUR_KERNEL, BLUR_KERNEL); //3x3 // 高斯滤波内核宽高可以不一样,但都必须正奇数
Imgproc.GaussianBlur(inMat, dst, ksize, 0, 0, Core.BORDER_DEFAULT);
}
中值滤波
用像素点领域灰度值的中值来代替该像素点的灰度值也就是说用一片区域的中间值来代替所有值。可以除去最大,最小值
除去斑点噪声和椒盐噪声很有用。均值滤波噪声也被参与运算
中值滤波时间在均值滤波的5倍以上
public static final int BLUR_KERNEL = 3; // 滤波内核大小必须是 正奇数
public static void medianBlur(Mat inMat, Mat dst) {
Size ksize = new Size(BLUR_KERNEL, BLUR_KERNEL); //3x3
Imgproc.MedianBlur(inMat, dst, ksize, 0, 0, Core.BORDER_DEFAULT);
}
均值滤波
均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。特别是椒盐噪声
public static final int BLUR_KERNEL = 5; // 滤波内核大小必须是 正奇数
public static void blur(Mat inMat, Mat dst) {
Point anchor = new Point(-1,-1);
Size ksize = new Size(BLUR_KERNEL, BLUR_KERNEL);
Imgproc.blur(inMat, dst, ksize, anchor, Core.BORDER_DEFAULT);
}
仿射变换
一般对图像的变化操作有放大、缩小、旋转等,统称为几何变换;主要的图像变换有:仿射变换、投影变换、极坐标变换; 对一个图像的图像变换主要有两大步骤:
实现空间坐标的转换,就是使图像从初始位置到终止位置的移动
使用一个插值算法完成输出图像的每个像素的灰度值
INTER_NEAREST 最近邻插值
INTER_LINEAR 双线性插值(默认)
INTER_AREA 使用像素区域关系进行重采样 缩小图像的时候使用
INTER_CUBIC 4x4像素邻域的双三次插值 放大图像的时候使用
INTER_LANCZOS4 8x8像素邻域的Lanczos插值
平移
平移是最简单的仿射变换;如将空间坐标(x,y)沿着x轴移动100,沿着y轴移动200。平移后的坐标为(x+100,y+200) 将这个过程一般化后,假设任意的空间坐标(x,y)先沿着x轴平移Px再沿着y轴平移Py。得到的坐标为(x+Px,y+Py)
/**
* @param pX 水平方向移动像素; 大于0则表示沿着轴正向移动,若小于0则表示沿着轴负向移动
* @param pY 垂直方向移动像素; 大于0则表示沿着轴正向移动,若小于0则表示沿着轴负向移动
*/
public static void translateImg(Mat inMat, Mat dst, int pX, int pY){
//定义平移矩阵 创建2行3列的全0矩阵;
// 正常应该3×3,但是最后一行取值已经固定为 0 0 1
Mat trans_mat = Mat.zeros(2, 3, CvType.CV_32FC1);
trans_mat.put(0, 0, 1);
trans_mat.put(0, 2, pX);
trans_mat.put(1, 1, 1);
trans_mat.put(1, 2, pY);
// 仿射变换 size如果使用inMat,则保持原有画布尺寸大小,使用dst的size,可以自行调整画布大小
Imgproc.warpAffine(inMat, dst, trans_mat, inMat.size());
}
运行教程
编号249-社区养老医疗综合服务平台
系统源码
进入公众号,在右上角有放大镜,就是搜索公众号内全部文章的题目,公众号各类的素材和相关的题目都可以通过这个方法来进行搜索。
输入要自己想要看的题材和对应的素材就可以了,因为的将各个类目的题材,都浓缩在题目里面, 所以只要是标题里面有的,或者涵盖了你的题目素材基本上都可以搜索的到。
关注微信公众号 “letcoding”---》源缘编程