opencv学习——OCR字符分割
1、读取灰度图像,使⽤threshold将其⼆值化,选择CV_THRESH_BINARY_INV,使得字符为⽩⾊
Mat input = imread("plate.jpg", 0);
Mat img_threshold;
threshold(input, img_threshold, 60, 255, CV_THRESH_BINARY_INV);
输⼊:
处理结果:
2、使⽤findContours接⼝函数出各字符的轮廓
vector<vector<Point>> contours;
findContours(img_contours, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
3、使⽤boundingRect函数得到各字符的外接矩形,⽤rectangle抠取字符图像
Rect mr = boundingRect(Mat(*(itc)));
rectangle(result, mr, Scalar(0, 255, 0));
4、使⽤verifySizes筛选字符图像
bool verifySizes(Mat r)
{
float aspect = 45.0f / 77.0f;
float charAspect = (ls / (ws;
float error = 0.35;
float minHeight = 15;
float maxHeight = 28;
//We have a different aspect ratio for number 1, and it can be ~0.2
float minAspect = 0.2;
float maxAspect = aspect + aspect*error;
float area = countNonZero(r);
float bbArea = r.ws;
float percPixels = area / bbArea;
if (percPixels < 0.8 && charAspect > minAspect && charAspect < maxAspect && r.rows >= minHeight && r.rows < maxHeight) return true;
else
return false;
}
5、对筛选后的字符图像进⾏预处理
Mat preprocessChar(Mat in)
{
//Remap image
int h = in.rows;
int w = in.cols;
Mat transformMat = Mat::eye(2, 3, CV_32F);
int m = max(w, h);
transformMat.at<float>(0, 2) = m / 2 - w / 2;
transformMat.at<float>(1, 2) = m / 2 - h / 2;
Mat warpImage(m, m, in.type());
warpAffine(in, warpImage, transformMat, warpImage.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0));
Mat out;
resize(warpImage, out, Size(20, 20));
return out;
}
6、将预处理后的字符图像及其在原图中的位置保持;因为findcontours算法得出的各字符的轮廓点是随机的,因此需要各字符图像的位置Rect,通过排序,得到真实的车牌字符顺序。
vector<pair<Mat, Rect>> output;
output.push_back(make_pair(auxRoi, mr));
最终结果:
完整代码如下:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
bool verifySizes(Mat r);
Mat preprocessChar(Mat in);
int main()
{
vector<pair<Mat, Rect>> output;
Mat input = imread("plate.jpg", 0);
Mat img_threshold;
threshold(input, img_threshold, 60, 255, CV_THRESH_BINARY_INV);
Mat img_contours;
pyTo(img_contours);
vector<vector<Point>> contours;
findContours(img_contours, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
Mat result;
pyTo(result);
cvtColor(result, result, CV_GRAY2RGB);
drawContours(result, contours, 6, Scalar(255, 0, 0), 1);
vector<vector<Point>>::iterator itc = contours.begin();
while (itc != d())
{
Rect mr = boundingRect(Mat(*(itc)));
rectangle(result, mr, Scalar(0, 255, 0));
Mat auxRoi = img_threshold(mr);
if (verifySizes(auxRoi))
{
auxRoi = preprocessChar(auxRoi);
auxRoi = preprocessChar(auxRoi);
output.push_back(make_pair(auxRoi, mr));
rectangle(result, mr, Scalar(0, 125, 255));
}
itc++;
}
imshow("result", result);
waitKey(0);
return 0;
}
bool verifySizes(Mat r)
{
//Char sizes 45x77
float aspect = 45.0f / 77.0f;
float charAspect = (ls / (ws;
float error = 0.35;
float minHeight = 15;
float maxHeight = 28;
/
/We have a different aspect ratio for number 1, and it can be ~0.2
float minAspect = 0.2;
float maxAspect = aspect + aspect*error;
//area of pixels
float area = countNonZero(r);
//bb area
float bbArea = r.ws;
//% of pixel in area
float percPixels = area / bbArea;
if (percPixels < 0.8 && charAspect > minAspect && charAspect < maxAspect && r.rows >= minHeight && r.rows < maxHeight) return true;
else
return false;
}
Mat preprocessChar(Mat in)
{
//Remap image
int h = in.rows;
int w = in.cols;
Mat transformMat = Mat::eye(2, 3, CV_32F);
int m = max(w, h);
transformMat.at<float>(0, 2) = m / 2 - w / 2;
transformMat.at<float>(1, 2) = m / 2 - h / 2;
Mat warpImage(m, m, in.type());
warpAffine(in, warpImage, transformMat, warpImage.size(), INTER_LINEAR, BORDER_CONSTANT, Scalar(0));
Mat out;
resize(warpImage, out, Size(20, 20));
return out;rectangle函数opencv
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论