前言
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);
運行結果: