前言
1.做文字识别相关的项目,首先是检测字符区域,然后进行水平切割,得到整行的文字,其次要考虑的就是怎么将每一个字符分开,并且从图片中切割下来,然后才可以导入训练好的模型进行字符识别。在字符单个切割的切割的过程中,可以使用OpenCV来实现。
2.我这里用到的OpenCV的版本是3.30,IDE是Qt和VS2015。
代码演示
void textCutting(Mat &src, vector<Mat> &out_char)
{
if (src.channels() > 1)
{
cvtColor(src, src, CV_BGR2GRAY);
}
//滤波
//GaussianBlur(src, src, Size(1, 1), 5, 5, 4);
adaptiveThreshold(src, src, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 41, 0);
//新建一个全白图像
Mat white_base(src.size(), src.type(), cv::Scalar(255));
//相减得到反转的图像
Mat input_src = white_base - src;
const int src_width = input_src.cols;
const int src_height = input_src.rows;
//储存每列白色像素个数的容器
//取列白色像素个数
vector<int> white_pice(src_width,0);
for (size_t i = 0; i < src_height; i++)
{
for (size_t j = 0; j < src_width; j++)
{
if (input_src.at<uchar>(i, j))
{
white_pice.at(j)++;
}
}
}
//绘制垂直投影下每列白色像素的数目
Mat vertical_projection(src_height, src_width, CV_8UC1, Scalar(0));
for (int i = 0; i< src_width; i++)
{
for (int j = 0; j < white_pice[i]; j++)
{
vertical_projection.at<uchar>(src_height - j - 1, i) = 255;
}
}
imshow("投影图", vertical_projection);
vector<Mat> split_src;
bool white_block = false;
bool black_block = false;
int temp_col_forword = 0, temp_col_behind = 0;
Mat split_temp;
for (int i = 0; i < src_width; i++)
{
//表示区域有白色像素
if (white_pice[i])
{
white_block = true;
black_block = false;
}
else
{ //若无白色像素(进入黑色区域)
if (white_block)
{
//若前一列有白色像素
temp_col_behind = i;
//取当前列为截止列
//截取下一部分
split_temp = input_src(Rect(temp_col_forword, 0, temp_col_behind - temp_col_forword, src_height)).clone();
split_src.push_back(split_temp);
}
//记录最新黑色区域的列号,记为起始列
temp_col_forword = i;
//表示进入黑色区域
black_block = true;
white_block = false;
}
}
for (int i = 0; i < split_src.size(); i++)
{
imshow(to_string(i), split_src[i]);
//out_char.push_back(split_src[i]);
}
}
函数调用:
Mat src;
src = imread("4.png");
vector<Mat> dst;
imshow("src", src);
textCutting(src, dst);
运行结果: