文章目录
- 引言
- 单层卷积神经网络(Single-layer CNN)
- 📌 单层 CNN 的基本结构
- 📌 单层 CNN 计算流程图像
- 透视变换矫正车牌c++实现
- 🪄关键代码实现:
- 🪄crnn结构图
- 使用jni实现高级Android开发
- 🎉java层如何调用c++层
- 车牌识别效果图
- 参考文章
引言
本文中使用的模型文件说明均采用ncnn模型格式适配安卓手机端以得到最大的运行推理速度可实现CPU加速以及GPU加速加速推理。
- 车牌检测模型:yolov5
- 车牌矫正:透视变换 车牌识别:crnn
- 车牌颜色识别:单层卷积神经网络
单层卷积神经网络(Single-layer CNN)
单层卷积神经网络(Single-layer CNN) 指的是 仅包含一个卷积层 的神经网络。它主要用于简单的图像特征提取任务,如边缘检测或简单的分类任务。
📌 单层 CNN 的基本结构
一个典型的 单层 CNN 由以下部分组成:
- 输入层(Input Layer)
- 例如输入一个
32×32×3
的 RGB 图像。
- 例如输入一个
- 单个卷积层(Single Convolutional Layer)
- 例如使用
5×5×3
大小的卷积核,共 6 个卷积核,stride=1,padding=0。
- 例如使用
- 激活函数(Activation Function)
- 例如 ReLU(Rectified Linear Unit)增加非线性表达能力。
- 池化层(Pooling Layer)
- 例如
2×2
的最大池化(Max Pooling),用于降维。
- 例如
- 全连接层(Fully Connected Layer, FC)
- 将卷积层输出的数据展平(Flatten),输入到全连接层。
- 输出层(Output Layer)
- 例如使用 Softmax 进行分类。
📌 单层 CNN 计算流程图像
假设输入图像是 32×32×3
(RGB 图像),使用 5×5×3
的卷积核,共 6 个卷积核,stride = 1,padding = 0。
透视变换矫正车牌c++实现
🪄关键代码实现:
for (size_t i=0; i<objects.size(); i++)
{
// letterbox pad to multiple of 32
cv::Mat image;
BitmapToMatrix(env, bitmap, image);
const Object& obj = objects[i];
// 计算车牌四个角点相对于车牌区域左上角的坐标
float new_x1 = objects[i].p3x - objects[i].x;
float new_y1 = objects[i].p3y - objects[i].y;
float new_x2 = objects[i].p4x - objects[i].x;
float new_y2 = objects[i].p4y - objects[i].y;
float new_x3 = objects[i].p2x - objects[i].x;
float new_y3 = objects[i].p2y - objects[i].y;
float new_x4 = objects[i].p1x - objects[i].x;
float new_y4 = objects[i].p1y - objects[i].y;
// 定义源图像的四个角点
cv::Point2f src_points[4];
// 定义目标图像的四个角点
cv::Point2f dst_points[4];
// 通过Image Watch查看的二维码四个角点坐标
src_points[0]=cv::Point2f(new_x1, new_y1);
src_points[1]=cv::Point2f(new_x2, new_y2);
src_points[2]=cv::Point2f(new_x3, new_y3);
src_points[3]=cv::Point2f(new_x4, new_y4);
// 期望透视变换后二维码四个角点的坐标
dst_points[0]=cv::Point2f(0.0, 0.0);
dst_points[1]=cv::Point2f(168.0, 0.0);
dst_points[2]=cv::Point2f(0.0, 48.0);
dst_points[3]=cv::Point2f(168.0, 48.0);
// 计算透视变换矩阵
cv::Mat rotation,img_warp;
cv::Rect_<float> rect;
rect.x = objects[i].x;
rect.y = objects[i].y;
rect.height = objects[i].h;
rect.width = objects[i].w;
// 提取车牌区域
cv::Mat ROI = image(rect);
// 计算透视变换矩阵
rotation=getPerspectiveTransform(src_points,dst_points);
// 应用透视变换,将车牌区域矫正为指定大小
warpPerspective(ROI,ROI,rotation,cv::Size(168, 48));
}
//具体看我给的源码实现。
- 下面是结构图
🪄crnn结构图
- 还可以参考此链接我写的另外一篇文章也是矫正的有异曲同工之处点击下面
- 三行代码实现文档智能校正
- crnn实现车牌数字识别
使用jni实现高级Android开发
🎉java层如何调用c++层
- 方法命名规则:C++ 层的 JNI 函数名需要遵循特定的命名规则,例如 Java_包名_类名_方法名。
- 数据类型转换:在 Java 和C++ 之间传递数据时,需要进行数据类型的转换,例如 jstring 和 std::string 之间的转换。
- 内存管理:在 JNI编程中,需要注意内存的分配和释放,避免内存泄漏。
- 如果需要更详细的教程请在评论区留言我下次更新就专门针对Android的高级开发进行讲解。
车牌识别效果图
参考文章
- 三行代码实现文档智能校正
- NCNN 官方文档:NCNN 是一个为手机端极致优化的高性能神经网络前向计算框架,本文使用 ncnn 模型格式适配安卓手机端,此文档提供了关于 NCNN 的详细介绍、使用方法和相关技术细节。
- YOLOv5 官方仓库:本文使用 YOLOv5 作为车牌检测模型,该仓库包含了 YOLOv5 的源代码、训练脚本、预训练模型等资源,有助于深入了解 YOLOv5 的原理和使用方式。
- OpenCV 官方文档:在车牌矫正部分使用了 OpenCV 的透视变换函数,此文档详细介绍了 OpenCV 的各种功能和 API,为计算机视觉开发提供了丰富的资源和指导。
- CRNN 相关论文:本文使用 CRNN 进行车牌识别,该论文是 CRNN 的原始论文,详细阐述了 CRNN 的架构和原理,对于理解和应用 CRNN 模型有很大的帮助。
- JNI 官方教程:在实现 Java 层调用 C++ 层代码时使用了 JNI 技术,该教程提供了关于 JNI 的详细规范和使用方法,是学习和使用 JNI 的重要参考资料。
- 通过结合 YOLOv 与 CNN 以及 OpenCV 算法实现了高精度的车牌识别。
如果以上内容有不足欢迎您的指出。