openCV 车牌号识别(车牌分类 汉字识别模型 数字字母识别模型)
机器学习:
- SVM 支持向量机
- ANN人工神经网络
SVM分类工具算法 使用正样本和负样本训练
图片去噪: 二值化和灰度化
车牌定位过程:
graph LR
A(高斯模糊)-->B(灰度化)
B-->C(边缘检测)
C-->D(二值化)
D-->E(闭操作)
E-->F(查找轮廓)
F-->G(筛选)
G-->H(角度尺寸矫正)
H-->I(SVM评测)
I-->J(确定定位)
-
高斯模糊
Mat blur; GaussianBlur(src,blur,size(5,5),0);
-
灰度化
Mat gray; cvtColor(blur,gray,COLOR_BGR2GRAY);
-
边缘检测
Mat sobel_16; sobel(gray,sobel_16,CV_165,1,0);
sobel算子仅能对灰度图像有效果,不能将色彩图像作为输入
调用时以16位保存数据, 后续显示需要转回8位
-
二值化
Mat shold; threshold(sobel,shold,0,255,THRESH_OTSU);
-
闭操作(膨胀腐蚀)
Mat close; Mat element = getStructuringElement(MORPH_RECT,size(17,3)); morphologyEx(shold,close,MORPH_CLOSE,element);
-
查找轮廓
vector<vector<Point>> contours; findContours(close,contours,RETR_EXTERNAL,CHAIN_APPROX_NONE); //遍历 vector<RotatedRect> vec_sobel_roi; for(vector<Point> point : contours){ RotatedRect rotatedRect = minAreaRect(point); rectangle(src,rotatedRect,boundingRect(),Scalar(255,0,255)); //初步筛选完全不符合的去除 if(verifysizes(rotatedRect)){ vec_sobel_roi,push_back(rotatedRect); } }
RotatedRect 带旋转角度的矩形 矫正角度倾斜的车牌 找出候选车牌
//矩形矫正(角度判断,旋转矩形,调整大小) tortuosity(src, vec_color_rects, dst);
机器学习:
- 从候选车牌确定最终车牌 SVM支持向量机的训练
- 从车牌中识别车牌字符 ANN人工神经网络
提取特征数据(常用LBP/HAAR/HOG)
Mat features;
getHogFeatures(svmHog,shold,features);
Mat samples = features.reshape(1,1);//将特征置位1行
//SVM评测 分值越低越有可能是车牌
float score = svm->predict(samples,noArray(),statModel::Flags::RAW_OUTPUT);
SVM训练必须是CV_32F1(表示数据为32位浮点型 单通道)
samples.converTo(samples,CV_32F1);
//ROW_SAMPLE 数据以一行保存
Prt<TrainData> trainData = TrainData::create(samples,SampleTypes::ROW_SAMPLE,labels);
创建SVM开始训练
Prt<SVM> classifier = SVM::create();
classifier->trainAuto(...);
classifier->save(...);
HSV/HSB颜色空间
openCV中 H值:100~140 S和V值:95~255 表示蓝色范围
Mat hsv;
cvtColor(src,hsv,COLOR_BGR2HSV);
//颜色匹配
int channels= hsv.channels();//共有3个通道 H\S\V
int h= hsv.rows;
int w = hsv.cols*channels;
if(hsv.isContinuous()){//判断是否是一行数据 矩阵是否连续
w*=h;
h=1;
}
for(size_t i=0;i<h;i++){
uchar *p = hsv.ptr<uchar>(i);
for(size)t j=0;j<w;j+=3){
int h = int(p[j]);
int s = int(p[j+1]);
int v = int(p[j+2]);
bool blue = false;
if (h >= 100 && h <= 140 &&
s >= 95 && s <= 255 &&
v >= 95 && v <= 255) {
blue = true;
}
if(blue){//将蓝色变白 将其他色变黑
p[j] = 0;
p[j+1]=0;
p[j+2]=255;
}else{
p[j] = 0;
p[j+1]=0;
p[j+2]=0;
}
}
}
字符分割与识别
文字轮廓检测问题 先找出第2个字母(通过7等分位置定位)
ANN人工神经网络