26 const bool CubeSearchObject::kUseCroppedChars =
true;
39 no_space_cost_ = NULL;
40 wid_ = samp_->
Width();
55 void CubeSearchObject::Cleanup() {
58 for (
int strt_seg = 0; strt_seg < segment_cnt_; strt_seg++) {
59 if (reco_cache_[strt_seg]) {
60 for (
int end_seg = 0; end_seg < segment_cnt_; end_seg++) {
61 if (reco_cache_[strt_seg][end_seg]) {
62 delete reco_cache_[strt_seg][end_seg];
65 delete []reco_cache_[strt_seg];
74 for (
int strt_seg = 0; strt_seg < segment_cnt_; strt_seg++) {
75 if (samp_cache_[strt_seg]) {
76 for (
int end_seg = 0; end_seg < segment_cnt_; end_seg++) {
77 if (samp_cache_[strt_seg][end_seg]) {
78 delete samp_cache_[strt_seg][end_seg];
81 delete []samp_cache_[strt_seg];
90 for (
int seg = 0; seg < segment_cnt_; seg++) {
92 delete segments_[seg];
100 delete []space_cost_;
104 if (no_space_cost_) {
105 delete []no_space_cost_;
106 no_space_cost_ = NULL;
115 if (!init_ && !Init())
117 return segment_cnt_ - 1;
121 bool CubeSearchObject::Init() {
129 reco_cache_ =
new CharAltList **[segment_cnt_];
131 samp_cache_ =
new CharSamp **[segment_cnt_];
133 for (
int seg = 0; seg < segment_cnt_; seg++) {
134 reco_cache_[seg] =
new CharAltList *[segment_cnt_];
135 memset(reco_cache_[seg], 0, segment_cnt_ *
sizeof(*reco_cache_[seg]));
137 samp_cache_[seg] =
new CharSamp *[segment_cnt_];
138 memset(samp_cache_[seg], 0, segment_cnt_ *
sizeof(*samp_cache_[seg]));
148 if (!init_ && !Init())
151 if (!IsValidSegmentRange(start_pt, end_pt))
155 if (samp_cache_ && samp_cache_[start_pt + 1] &&
156 samp_cache_[start_pt + 1][end_pt]) {
157 return samp_cache_[start_pt + 1][end_pt];
163 end_pt - start_pt, NULL,
164 &left_most, &right_most, hgt_);
168 if (kUseCroppedChars) {
178 int char_top = samp->
Top();
179 int char_wid = samp->
Width();
180 int char_hgt = samp->
Height();
186 bool first_char = rtl_ ? right_most : left_most;
187 bool last_char = rtl_ ? left_most : right_most;
195 samp->
SetLastChar((end_pt == (segment_cnt_ - 1)) ? 255 : 0);
202 samp_cache_[start_pt + 1][end_pt] = samp;
207 if (!init_ && !Init())
209 if (!IsValidSegmentRange(start_pt, end_pt)) {
210 fprintf(stderr,
"Cube ERROR (CubeSearchObject::CharBox): invalid " 211 "segment range (%d, %d)\n", start_pt, end_pt);
220 end_pt - start_pt, NULL,
221 &left_most, &right_most, hgt_);
224 if (kUseCroppedChars) {
232 Box *box = boxCreate(samp->
Left(), samp->
Top(),
242 if (!init_ && !Init()) {
243 fprintf(stderr,
"Cube ERROR (CubeSearchObject::RecognizeSegment): could " 244 "not initialize CubeSearchObject\n");
249 if (!IsValidSegmentRange(start_pt, end_pt)) {
250 fprintf(stderr,
"Cube ERROR (CubeSearchObject::RecognizeSegment): invalid " 251 "segment range (%d, %d)\n", start_pt, end_pt);
256 if (reco_cache_ && reco_cache_[start_pt + 1] &&
257 reco_cache_[start_pt + 1][end_pt]) {
258 return reco_cache_[start_pt + 1][end_pt];
264 fprintf(stderr,
"Cube ERROR (CubeSearchObject::RecognizeSegment): could " 265 "not construct CharSamp\n");
271 if (char_classifier) {
272 reco_cache_[start_pt + 1][end_pt] = char_classifier->
Classify(samp);
276 fprintf(stderr,
"Cube WARNING (CubeSearchObject::RecognizeSegment): cube " 277 "context has no character classifier!! Inventing a probability " 281 int seg_cnt = end_pt - start_pt;
282 double prob_val = (1.0 / class_cnt) *
283 exp(-fabs(seg_cnt - 2.0)) *
284 exp(-samp->
Width() /
static_cast<double>(samp->
Height()));
286 for (
int class_idx = 0; class_idx < class_cnt; class_idx++) {
289 reco_cache_[start_pt + 1][end_pt] = alt_list;
292 return reco_cache_[start_pt + 1][end_pt];
298 bool CubeSearchObject::Segment() {
302 segments_ = samp_->
Segment(&segment_cnt_, rtl_,
305 if (!segments_ || segment_cnt_ <= 0) {
308 if (segment_cnt_ >= kMaxSegmentCnt) {
315 bool CubeSearchObject::ComputeSpaceCosts() {
317 if (!init_ && !Init())
325 if (segment_cnt_ < 2)
330 int *max_left_x =
new int[segment_cnt_ - 1];
331 int *min_right_x =
new int[segment_cnt_ - 1];
333 min_right_x[0] = segments_[0]->
Left();
334 max_left_x[segment_cnt_ - 2] = segments_[segment_cnt_ - 1]->
Right();
335 for (
int pt_idx = 1; pt_idx < (segment_cnt_ - 1); pt_idx++) {
336 min_right_x[pt_idx] =
337 MIN(min_right_x[pt_idx - 1], segments_[pt_idx]->Left());
338 max_left_x[segment_cnt_ - pt_idx - 2] =
339 MAX(max_left_x[segment_cnt_ - pt_idx - 1],
340 segments_[segment_cnt_ - pt_idx - 1]->Right());
343 min_right_x[segment_cnt_ - 2] = segments_[segment_cnt_ - 1]->
Left();
344 max_left_x[0] = segments_[0]->
Right();
345 for (
int pt_idx = 1; pt_idx < (segment_cnt_ - 1); pt_idx++) {
346 min_right_x[segment_cnt_ - pt_idx - 2] =
347 MIN(min_right_x[segment_cnt_ - pt_idx - 1],
348 segments_[segment_cnt_ - pt_idx - 1]->Left());
350 MAX(max_left_x[pt_idx - 1], segments_[pt_idx]->Right());
356 space_cost_ =
new int[segment_cnt_ - 1];
357 no_space_cost_ =
new int[segment_cnt_ - 1];
363 for (
int pt_idx = 0; pt_idx < (segment_cnt_ - 1); pt_idx++) {
365 int gap = min_right_x[pt_idx] - max_left_x[pt_idx];
369 if (gap < min_spc_gap_ || max_spc_gap_ == min_spc_gap_) {
371 }
else if (gap > max_spc_gap_) {
376 prob = (gap - min_spc_gap_) /
377 static_cast<double>(max_spc_gap_ - min_spc_gap_);
386 delete []min_right_x;
394 if (!space_cost_ && !ComputeSpaceCosts()) {
398 return space_cost_[pt_idx];
405 if (!space_cost_ && !ComputeSpaceCosts())
407 return no_space_cost_[pt_idx];
414 if (!space_cost_ && !ComputeSpaceCosts())
417 for (
int pt_idx = st_pt + 1; pt_idx < end_pt; pt_idx++)
double MaxSpaceHeightRatio() const
unsigned short Height() const
ReadOrder ReadingOrder() const
CubeSearchObject(CubeRecoContext *cntxt, CharSamp *samp)
virtual CharAltList * Classify(CharSamp *char_samp)=0
bool Insert(int class_id, int cost, void *tag=NULL)
void SetFirstChar(unsigned short first_char)
void SetNormAspectRatio(unsigned short norm_aspect_ratio)
unsigned short Width() const
CharClassifier * Classifier() const
int MaxSegPerChar() const
static int Prob2Cost(double prob_val)
int SpaceCost(int seg_pt)
unsigned short Top() const
TuningParams * Params() const
ConComp ** Segment(int *seg_cnt, bool right_2_left, int max_hist_wnd, int min_con_comp_size) const
void SetNormBottom(unsigned short norm_bottom)
double MinSpaceHeightRatio() const
int NoSpaceCost(int seg_pt)
CharSet * CharacterSet() const
Box * CharBox(int start_pt, int end_pt)
CharSamp * CharSample(int start_pt, int end_pt)
void SetNormTop(unsigned short norm_top)
CharAltList * RecognizeSegment(int start_pt, int end_pt)
unsigned short Left() const
static CharSamp * FromConComps(ConComp **concomp_array, int strt_concomp, int seg_flags_size, int *seg_flags, bool *left_most, bool *right_most, int word_hgt)
int MinConCompSize() const
void SetLastChar(unsigned short last_char)