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_];
130 if (reco_cache_ ==
NULL) {
131 fprintf(stderr,
"Cube ERROR (CubeSearchObject::Init): could not "
132 "allocate CharAltList array\n");
136 samp_cache_ =
new CharSamp **[segment_cnt_];
137 if (samp_cache_ ==
NULL) {
138 fprintf(stderr,
"Cube ERROR (CubeSearchObject::Init): could not "
139 "allocate CharSamp array\n");
143 for (
int seg = 0; seg < segment_cnt_; seg++) {
144 reco_cache_[seg] =
new CharAltList *[segment_cnt_];
145 if (reco_cache_[seg] ==
NULL) {
146 fprintf(stderr,
"Cube ERROR (CubeSearchObject::Init): could not "
147 "allocate a single segment's CharAltList array\n");
151 memset(reco_cache_[seg], 0, segment_cnt_ *
sizeof(*reco_cache_[seg]));
153 samp_cache_[seg] =
new CharSamp *[segment_cnt_];
154 if (samp_cache_[seg] ==
NULL) {
155 fprintf(stderr,
"Cube ERROR (CubeSearchObject::Init): could not "
156 "allocate a single segment's CharSamp array\n");
160 memset(samp_cache_[seg], 0, segment_cnt_ *
sizeof(*samp_cache_[seg]));
170 if (!init_ && !Init())
173 if (!IsValidSegmentRange(start_pt, end_pt))
177 if (samp_cache_ && samp_cache_[start_pt + 1] &&
178 samp_cache_[start_pt + 1][end_pt]) {
179 return samp_cache_[start_pt + 1][end_pt];
185 end_pt - start_pt,
NULL,
186 &left_most, &right_most, hgt_);
190 if (kUseCroppedChars) {
200 int char_top = samp->
Top();
201 int char_wid = samp->
Width();
202 int char_hgt = samp->
Height();
208 bool first_char = rtl_ ? right_most : left_most;
209 bool last_char = rtl_ ? left_most : right_most;
217 samp->
SetLastChar((end_pt == (segment_cnt_ - 1)) ? 255 : 0);
224 samp_cache_[start_pt + 1][end_pt] = samp;
229 if (!init_ && !Init())
231 if (!IsValidSegmentRange(start_pt, end_pt)) {
232 fprintf(stderr,
"Cube ERROR (CubeSearchObject::CharBox): invalid "
233 "segment range (%d, %d)\n", start_pt, end_pt);
242 end_pt - start_pt,
NULL,
243 &left_most, &right_most, hgt_);
246 if (kUseCroppedChars) {
254 Box *box = boxCreate(samp->
Left(), samp->
Top(),
264 if (!init_ && !Init()) {
265 fprintf(stderr,
"Cube ERROR (CubeSearchObject::RecognizeSegment): could "
266 "not initialize CubeSearchObject\n");
271 if (!IsValidSegmentRange(start_pt, end_pt)) {
272 fprintf(stderr,
"Cube ERROR (CubeSearchObject::RecognizeSegment): invalid "
273 "segment range (%d, %d)\n", start_pt, end_pt);
278 if (reco_cache_ && reco_cache_[start_pt + 1] &&
279 reco_cache_[start_pt + 1][end_pt]) {
280 return reco_cache_[start_pt + 1][end_pt];
286 fprintf(stderr,
"Cube ERROR (CubeSearchObject::RecognizeSegment): could "
287 "not construct CharSamp\n");
293 if (char_classifier) {
294 reco_cache_[start_pt + 1][end_pt] = char_classifier->
Classify(samp);
298 fprintf(stderr,
"Cube WARNING (CubeSearchObject::RecognizeSegment): cube "
299 "context has no character classifier!! Inventing a probability "
303 int seg_cnt = end_pt - start_pt;
304 double prob_val = (1.0 / class_cnt) *
305 exp(-fabs(seg_cnt - 2.0)) *
306 exp(-samp->
Width() /
static_cast<double>(samp->
Height()));
309 for (
int class_idx = 0; class_idx < class_cnt; class_idx++) {
312 reco_cache_[start_pt + 1][end_pt] = alt_list;
316 return reco_cache_[start_pt + 1][end_pt];
322 bool CubeSearchObject::Segment() {
326 segments_ = samp_->
Segment(&segment_cnt_, rtl_,
329 if (!segments_ || segment_cnt_ <= 0) {
332 if (segment_cnt_ >= kMaxSegmentCnt) {
339 bool CubeSearchObject::ComputeSpaceCosts() {
341 if (!init_ && !Init())
349 if (segment_cnt_ < 2)
354 int *max_left_x =
new int[segment_cnt_ - 1];
355 int *min_right_x =
new int[segment_cnt_ - 1];
356 if (!max_left_x || !min_right_x) {
357 delete []min_right_x;
362 min_right_x[0] = segments_[0]->
Left();
363 max_left_x[segment_cnt_ - 2] = segments_[segment_cnt_ - 1]->
Right();
364 for (
int pt_idx = 1; pt_idx < (segment_cnt_ - 1); pt_idx++) {
365 min_right_x[pt_idx] =
366 MIN(min_right_x[pt_idx - 1], segments_[pt_idx]->Left());
367 max_left_x[segment_cnt_ - pt_idx - 2] =
368 MAX(max_left_x[segment_cnt_ - pt_idx - 1],
369 segments_[segment_cnt_ - pt_idx - 1]->Right());
372 min_right_x[segment_cnt_ - 2] = segments_[segment_cnt_ - 1]->
Left();
373 max_left_x[0] = segments_[0]->
Right();
374 for (
int pt_idx = 1; pt_idx < (segment_cnt_ - 1); pt_idx++) {
375 min_right_x[segment_cnt_ - pt_idx - 2] =
376 MIN(min_right_x[segment_cnt_ - pt_idx - 1],
377 segments_[segment_cnt_ - pt_idx - 1]->Left());
379 MAX(max_left_x[pt_idx - 1], segments_[pt_idx]->Right());
385 space_cost_ =
new int[segment_cnt_ - 1];
386 no_space_cost_ =
new int[segment_cnt_ - 1];
387 if (!space_cost_ || !no_space_cost_) {
388 delete []min_right_x;
397 for (
int pt_idx = 0; pt_idx < (segment_cnt_ - 1); pt_idx++) {
399 int gap = min_right_x[pt_idx] - max_left_x[pt_idx];
403 if (gap < min_spc_gap_) {
405 }
else if (gap > max_spc_gap_) {
410 prob = (gap - min_spc_gap_) /
411 static_cast<double>(max_spc_gap_ - min_spc_gap_);
420 delete []min_right_x;
428 if (!space_cost_ && !ComputeSpaceCosts()) {
432 return space_cost_[pt_idx];
439 if (!space_cost_ && !ComputeSpaceCosts())
441 return no_space_cost_[pt_idx];
448 if (!space_cost_ && !ComputeSpaceCosts())
451 for (
int pt_idx = st_pt + 1; pt_idx < end_pt; pt_idx++)
double MaxSpaceHeightRatio() const
bool Insert(int class_id, int cost, void *tag=NULL)
double MinSpaceHeightRatio() const
int NoSpaceCost(int seg_pt)
void SetNormBottom(unsigned short norm_bottom)
static int Prob2Cost(double prob_val)
int MaxSegPerChar() const
CharAltList * RecognizeSegment(int start_pt, int end_pt)
unsigned short Left() const
ReadOrder ReadingOrder() const
int SpaceCost(int seg_pt)
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)
unsigned short Width() const
Box * CharBox(int start_pt, int end_pt)
void SetLastChar(unsigned short last_char)
void SetFirstChar(unsigned short first_char)
CharSamp * CharSample(int start_pt, int end_pt)
virtual CharAltList * Classify(CharSamp *char_samp)=0
CharClassifier * Classifier() const
TuningParams * Params() const
ConComp ** Segment(int *seg_cnt, bool right_2_left, int max_hist_wnd, int min_con_comp_size) const
unsigned short Top() const
int MinConCompSize() const
CharSet * CharacterSet() const
void SetNormAspectRatio(unsigned short norm_aspect_ratio)
unsigned short Height() const
void SetNormTop(unsigned short norm_top)
CubeSearchObject(CubeRecoContext *cntxt, CharSamp *samp)