#include <windows.h>
#include <iostream>
#include <opencv2/opencv.hpp>
//用于截取图片上的车牌
using namespace cv;
using namespace std;
using namespace ml;
const string chars[34]
{
"0","1","2","3","4","5","6","7","8","9",
"A","B","C","D","E","F","G","H","J","K",
"L","M","N","P","Q","R","S","T","U","V",
"W","X","Y","Z"
};
const string chineses[20]
{
"浙","皖","京","渝","闽","甘","粤","桂","贵","琼",
"冀","黑","豫","鄂","湘","苏","赣","吉","辽","蒙"
};
int H_data = 100;
int S_data = 125;
int V_data = 50;
int H_data_max = 125;
int S_data_max = 255;
int V_data_max = 245;
void canny_track1(int, void *)
{
}
void canny_track2(int, void *)
{
}
void canny_track3(int, void *)
{
}
void canny_track4(int, void *)
{
}
void canny_track5(int, void *)
{
}
void canny_track6(int, void *)
{
}
void can_chang()
{
namedWindow("【HSV色域阈值调节】", WINDOW_NORMAL);
cv::createTrackbar("H_MIN", "【HSV色域阈值调节】", &H_data, 255, canny_track1);
canny_track1(0, 0);
cv::createTrackbar("S_MIN", "【HSV色域阈值调节】", &S_data, 255, canny_track2);
canny_track2(0, 0);
cv::createTrackbar("V_MIN", "【HSV色域阈值调节】", &V_data, 255, canny_track3);
canny_track3(0, 0);
cv::createTrackbar("H_MAX", "【HSV色域阈值调节】", &H_data_max, 255, canny_track4);
canny_track4(0, 0);
cv::createTrackbar("S_MAX", "【HSV色域阈值调节】", &S_data_max, 255, canny_track5);
canny_track5(0, 0);
cv::createTrackbar("V_MAX", "【HSV色域阈值调节】", &V_data_max, 255, canny_track6);
canny_track6(0, 0);
}
void filter_backdrop(Mat &img)
{
Mat img_HSV = img.clone();//复制
cvtColor(img, img, COLOR_BGR2GRAY);
cvtColor(img_HSV, img_HSV, COLOR_BGR2HSV);
int x = 0;
int y = 0;
for (y = 0; y < img_HSV.rows; y++)
{
for (x = 0; x < img_HSV.cols; x++)
{
/*if (x <img_HSV.cols / 4 ||x > img_HSV.cols / 4 * 3)
{
img.at<uchar>(y, x) = 255;
}
else */if ((img_HSV.at<Vec3b>(y, x)[0] <= H_data_max&&img_HSV.at<Vec3b>(y, x)[0] >= H_data) &&
(img_HSV.at<Vec3b>(y, x)[1] <= S_data_max&&img_HSV.at<Vec3b>(y, x)[1] >= S_data) &&
(img_HSV.at<Vec3b>(y, x)[2] <= V_data_max&&img_HSV.at<Vec3b>(y, x)[2] >= V_data))
{
img.at<uchar>(y, x) = 255;
}
else
{
img.at<uchar>(y, x) = 0;
}
}
}
//imshow("【滤除背景后的灰度图】", img);
}
const int image_cols = 16;
const int image_rows = 20;
void discern_car(Mat image,vector<Mat> & img_buff,string &chr_chars)//识别图片
{
Ptr<ANN_MLP> bp_chinese = StatModel::load<ANN_MLP>("../bpcharModel_chinese.xml");
Ptr<ANN_MLP> bp_char = StatModel::load<ANN_MLP>("../bpcharModel_16_20.xml");
Mat grayImg = image.clone();
filter_backdrop(grayImg);
//Candy/sobel 边缘检测:
Mat candy_image;
Canny(grayImg, candy_image, 500, 200, 3);
//imshow("边沿检测", candy_image);
//形态学处理
//图片膨胀处理
Mat dilate_image, erode_image;
//自定义 核进行 x 方向的膨胀腐蚀
Mat elementX = getStructuringElement(MORPH_RECT, Size(40, 1));
Mat elementY = getStructuringElement(MORPH_RECT, Size(1, 19));
Point point(-1, -1);
dilate(candy_image, dilate_image, elementX, point, 2);
erode(dilate_image, erode_image, elementX, point, 4);
dilate(erode_image, dilate_image, elementX, point, 2);
//自定义 核进行 Y 方向的膨胀腐蚀
erode(dilate_image, erode_image, elementY, point, 1);
dilate(erode_image, dilate_image, elementY, point, 2);
//噪声处理
//平滑处理 中值滤波
Mat blurr_image;
medianBlur(dilate_image, blurr_image, 3);
//imshow("腐蚀膨胀", blurr_image);
//矩形轮廓查找与筛选:
Mat contour_image;
//深拷贝 查找轮廓会改变源图像信息,需要重新 拷贝 图像
contour_image = blurr_image.clone();
//查找图像轮廓
Mat midImg3(contour_image.rows, contour_image.cols, CV_8UC3, Scalar::all(0));
vector<vector<Point>> contours;
findContours(contour_image, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
//轮廓表示为一个矩形 车牌提取
Mat roi_image;
//截取车牌图像
for (int i = 0; i < contours.size(); i++) {
Rect r = boundingRect(Mat(contours[i]));
//RotatedRect r = minAreaRect(Mat(contours[i]));
if ((float)r.width / r.height >= 2.2 && (float)r.width / r.height <= 3.6) {
rectangle(contour_image, r, Scalar(0, 0, 255), 2);
roi_image = image(r);
}
}
//重映射大小
resize(roi_image, roi_image, Size(210, 70), (0, 0), (0, 0), INTER_AREA);//使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现
img_buff.push_back(roi_image);//车牌图片
//灰度图
Mat roi_gray_image;
cvtColor(roi_image, roi_gray_image, COLOR_BGR2GRAY);
//腐蚀膨胀消除黑点
Mat src = roi_gray_image.clone();//复制
Mat dst;
Mat structureElement = getStructuringElement(MORPH_RECT, Size(4, 3), Point(-1, -1)); //创建结构元
dilate(src, dst, structureElement, Point(-1, -1), 1); //调用膨胀API
erode(dst, dst, structureElement); //调用腐蚀API
Mat test_image;//复制
threshold(dst, test_image, 0, 255,THRESH_OTSU);
Mat gray = test_image.clone();
Mat grays = test_image.clone();
vector<vector<Point>> contours_buff; //定义轮廓集合
vector<Vec4i> hierarchy;
findContours(gray, contours_buff, hierarchy, RETR_TREE, CHAIN_APPROX_NONE);//CV_RETR_EXTERNAL只检测外部轮廓
vector<Rect> Rects;//用于保存边沿框
int width_v = 0;
for (int index_ori = 0; index_ori >= 0; index_ori = hierarchy[index_ori][0])
{
if (contours_buff.size() == 0)break;
if (index_ori < 0)break;
drawContours(grays, contours_buff, index_ori, Scalar(255), 1, 8, hierarchy);
Rect rect = boundingRect(contours_buff[index_ori]);//检测外轮廓
rect.x-=1;
rect.y-=1;
rect.width += 2;
rect.height += 2;
if (rect.x < 0)rect.x = 0;
if (rect.y < 0)rect.y = 0;
if (rect.width + rect.x > roi_gray_image.cols)rect.width = roi_gray_image.cols - rect.x;
if (rect.height + rect.y > roi_gray_image.rows)rect.height = roi_gray_image.rows - rect.y;
if (rect.width<roi_gray_image.cols /7 && rect.height>roi_gray_image.rows *0.6 && rect.height<roi_gray_image.rows *0.85)//一个车牌最多7个字符 进行初步的筛选
{
Rects.push_back(rect);//记录后对容器内的数据进行排序 基本就是需要的边沿
if ((float)rect.width / rect.height >= 0.3 && (float)rect.width / rect.height <= 0.7)//锁定长宽比例 //这个基本是正确的
{
//计算平均长度
width_v += rect.width;
width_v /= 2;
}
}
}
//对边沿进行排序和适当处理
for (int i=0; i < Rects.size(); i++)
{
if (!((float)Rects[i].width / Rects[i].height >= 0.3 && (float)Rects[i].width / Rects[i].height <= 0.7))//锁定长宽比例 //这个基本是正确的
{
Rects[i].x =Rects[i].x +(Rects[i].width - width_v) / 2;
Rects[i].width = width_v;
if (Rects[i].width + Rects[i].x > roi_gray_image.cols)Rects[i].width = roi_gray_image.cols - Rects[i].x;
if (Rects[i].height + Rects[i].y > roi_gray_image.rows)Rects[i].height = roi_gray_image.rows - Rects[i].y;
}
}
//排序
for (int i = Rects.size(); i >=0; i--)
{
for (int x = 0; x < i-1; x++)
{
if (Rects[x + 1].x < Rects[x].x)
{
Rect Rects_buff;
Rects_buff.x = Rects[x].x;
Rects_buff.y = Rects[x].y;
Rects_buff.width = Rects[x].width;
Rects_buff.height= Rects[x].height;
Rects[x].x = Rects[x+1].x;
Rects[x].y = Rects[x+1].y;
Rects[x].width = Rects[x+1].width;
Rects[x].height = Rects[x+1].height;
Rects[x+1].x = Rects_buff.x
没有合适的资源?快使用搜索试试~ 我知道了~
QT5.9.1+opencv4.1.0车牌识别
共47个文件
obj:8个
xml:7个
h:6个
需积分: 45 42 下载量 79 浏览量
2020-12-27
14:46:04
上传
评论 11
收藏 6.25MB ZIP 举报
温馨提示
该项目在博客里有详细介绍,这是QT版代码。
资源详情
资源评论
资源推荐
收起资源包目录
car.zip (47个子文件)
car
1 (5).jpg 94KB
1 (1).jpg 35KB
1 (6).jpg 30KB
car
car.cpp 16KB
car.h 142B
mainwindow.cpp 4KB
car.pro.user 23KB
.idea
workspace.xml 1KB
car.iml 291B
inspectionProfiles
profiles_settings.xml 174B
modules.xml 265B
mainwindow.h 583B
main.cpp 183B
car.pro 1KB
mainwindow.ui 5KB
bpcharModel_16_20.xml 2.12MB
1 (7).jpg 39KB
build-car-Desktop_Qt_5_9_2_MSVC2015_32bit-Debug
Makefile 29KB
release
Makefile.Debug 70KB
debug
car.ilk 2.12MB
moc_mainwindow.obj 429KB
moc_predefs.h 260B
car.exe 229KB
car.obj 790KB
car.vc.pdb 3.59MB
mainwindow.obj 706KB
moc_mainwindow.cpp 4KB
main.obj 427KB
car.pdb 4.97MB
bpcharModel_16_20.xml 2.12MB
ui_mainwindow.h 9KB
Makefile.Release 70KB
.qmake.stash 1KB
bpcharModel_chinese.xml 2.07MB
1 (4).jpg 38KB
build-car-Desktop_Qt_5_9_2_MSVC2015_32bit-Release
Makefile 29KB
release
moc_mainwindow.obj 85KB
moc_predefs.h 243B
car.obj 164KB
mainwindow.obj 193KB
moc_mainwindow.cpp 4KB
main.obj 84KB
Makefile.Debug 66KB
debug
ui_mainwindow.h 9KB
Makefile.Release 66KB
.qmake.stash 1KB
bpcharModel_chinese.xml 2.07MB
共 47 条
- 1
MMC_mini
- 粉丝: 42
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0