Skip to content

Commit

Permalink
finish char bounding box
Browse files Browse the repository at this point in the history
  • Loading branch information
yq committed Nov 24, 2018
1 parent 8bb2f87 commit d6f70a3
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 40 deletions.
10 changes: 4 additions & 6 deletions include/ocr_extractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define OCR_EXTRACTOR_H

#include <vector>
#include <algorithm>
#include <opencv2/opencv.hpp>

using namespace std;
Expand All @@ -10,14 +11,11 @@ class OcrExtractor {

public:

int ref_imgs_n {0};
cv::Size ref_img_size;
int symbol_height {0};
int blank_height {0};
int roi_idx;
vector<cv::Mat> roi_arr;

OcrExtractor();
void add_ref_img(const cv::Mat & piece_img);

void add_img(const cv::Mat & piece);

};

Expand Down
97 changes: 63 additions & 34 deletions src/ocr_extractor.cpp
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
#include <ocr_extractor.h>

OcrExtractor::OcrExtractor() {

}

void OcrExtractor::add_ref_img(const cv::Mat & piece_img) {

if (ref_imgs_n == 0) {
ref_img_size = piece_img.size();
}
}

ref_imgs_n++;
void OcrExtractor::add_img(const cv::Mat & piece) {

cv::Mat gray_img, col_mean;
cv::cvtColor(piece_img, gray_img, cv::COLOR_BGR2GRAY);
cv::cvtColor(piece, gray_img, cv::COLOR_BGR2GRAY);
cv::reduce(gray_img, col_mean, 1, cv::REDUCE_AVG, CV_32FC1);
cv::normalize(col_mean, col_mean, 0, 255, cv::NORM_MINMAX, CV_8UC1);
cv::threshold(col_mean, col_mean, 128, 255, cv::THRESH_BINARY);
cv::threshold(col_mean, col_mean, 200, 255, cv::THRESH_BINARY);

int state = 0;
int index_st = 0;
int tmp_blank_height = 0;
int tmp_blank_n = 0;
int tmp_symbol_height = 0;
int tmp_symbol_n = 0;
vector<int> blank_y_arr;
vector<int> symbol_y_arr;

for (int y = 1; y < ref_img_size.height - 1; y++) {
for (int y = 0; y < piece.rows; y++) {

bool stable_flag = true;
int self_val = col_mean.at<uchar>(y, 0);
// cout << "self_val " << self_val << endl;

for (int i = -2; i < 3; i++) {
if (y + i < 0 || y + i >= ref_img_size.height) continue;
if (y + i < 0 || y + i >= piece.rows) continue;
if (col_mean.at<uchar>(y + i, 0) != self_val) {
stable_flag = false;
break;
Expand All @@ -42,33 +32,72 @@ void OcrExtractor::add_ref_img(const cv::Mat & piece_img) {
if (!stable_flag) continue;

switch (state) {
case 0:
index_st = y;
if (self_val == 0) {
case 0: // unknown
if (self_val == 255) {
state = -1;
symbol_y_arr.push_back(y);
} else {
state = 1;
}
break;
case -1:
if (self_val == 0) continue;
tmp_blank_height += y - index_st;
tmp_blank_n++;
case -1: // blank
if (self_val == 255) continue;
blank_y_arr.push_back(y);
state = 1;
index_st = y;
break;
case 1:
if (self_val == 255) continue;
tmp_symbol_height += y - index_st;
tmp_symbol_n++;
case 1: // symbol
if (self_val == 0) continue;
symbol_y_arr.push_back(y);
state = -1;
index_st = y;
break;
}
// cout << y << " " << col_mean.at<float>(y, 0) << endl;;
// vert_hist[y] += col_mean.at<float>(y, 0);

}

if (state == -1) blank_y_arr.push_back(piece.rows);

#ifdef DEBUG
cv::Mat tmp_img = piece.clone();
#endif

int blank_y_idx = 0;
vector<int> symbol_block_y_arr;
for (int symbol_y: symbol_y_arr) {
while (blank_y_idx < blank_y_arr.size() && blank_y_arr[blank_y_idx] <= symbol_y) blank_y_idx++;
int symbol_block_y = (symbol_y + blank_y_arr[blank_y_idx]) >> 1;
symbol_block_y_arr.push_back(symbol_block_y);
blank_y_idx++;

#ifdef DEBUG
cout <<symbol_y << " " << blank_y_arr[blank_y_idx - 1] << " " << symbol_block_y << endl;
cv::line(tmp_img, cv::Point(0, symbol_block_y), cv::Point(piece.cols-1, symbol_block_y), cv::Scalar(0, 200, 0), 1);
#endif
}

cout << tmp_blank_height / tmp_blank_n << " " << tmp_symbol_height / tmp_symbol_n << endl;
#ifdef DEBUG
cout << endl;
cv::imshow("piece", piece);
cv::imshow("tmp", tmp_img);
cv::waitKey();
#endif

roi_arr.clear();
roi_idx = 0;
for (int i = 1; i < (int)symbol_y_arr.size(); i++) {

int y0 = symbol_block_y_arr[i - 1];
int y1 = symbol_block_y_arr[i];
int margin = int((y1 - y0) * 0.1);
y0 = max(0, y0 - margin);
y1 = min(piece.rows, y1 + margin);

int height = y1 - y0;
int width = min(height, piece.cols);
int x0 = (piece.cols - width) >> 1;

cv::Rect roi_rect(x0, y0, width, height);
roi_arr.push_back(piece(roi_rect).clone());

}

}

0 comments on commit d6f70a3

Please sign in to comment.