tesseract/ccstruct/ocrblock.h
Ray Smith 0e868ef377 Major change to improve layout analysis for heavily diacritic languages:
Tha, Vie, Kan, Tel etc.
There is a new overlap detector that detects when diacritics
cause a big increase in textline overlap. In such cases, diacritics from
overlap regions are kept separate from layout analysis completely, allowing
textline formation to happen without them. The diacritics are then assigned
to 0, 1 or 2 close words at the end of layout analysis, using and modifying
an old noise detection data path.
The stored diacritics are used or not during recognition according to the
character classifier's liking for them.
2015-05-12 16:47:02 -07:00

238 lines
6.9 KiB
C++

/**********************************************************************
* File: ocrblock.h (Formerly block.h)
* Description: Page block class definition.
* Author: Ray Smith
* Created: Thu Mar 14 17:32:01 GMT 1991
*
* (C) Copyright 1991, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/
#ifndef OCRBLOCK_H
#define OCRBLOCK_H
#include "ocrpara.h"
#include "ocrrow.h"
#include "pdblock.h"
class BLOCK; //forward decl
ELISTIZEH (BLOCK)
class BLOCK:public ELIST_LINK, public PDBLK
//page block
{
friend class BLOCK_RECT_IT; //block iterator
public:
BLOCK()
: re_rotation_(1.0f, 0.0f),
classify_rotation_(1.0f, 0.0f),
skew_(1.0f, 0.0f) {
right_to_left_ = false;
hand_poly = NULL;
}
BLOCK(const char *name, //< filename
BOOL8 prop, //< proportional
inT16 kern, //< kerning
inT16 space, //< spacing
inT16 xmin, //< bottom left
inT16 ymin,
inT16 xmax, //< top right
inT16 ymax);
~BLOCK () {
}
/**
* set space size etc.
* @param prop proportional
* @param kern inter char size
* @param space inter word size
* @param ch_pitch pitch if fixed
*/
void set_stats(BOOL8 prop,
inT16 kern,
inT16 space,
inT16 ch_pitch) {
proportional = prop;
kerning = (inT8) kern;
spacing = space;
pitch = ch_pitch;
}
/// set char size
void set_xheight(inT32 height) {
xheight = height;
}
/// set font class
void set_font_class(inT16 font) {
font_class = font;
}
/// return proportional
BOOL8 prop() const {
return proportional;
}
bool right_to_left() const {
return right_to_left_;
}
void set_right_to_left(bool value) {
right_to_left_ = value;
}
/// return pitch
inT32 fixed_pitch() const {
return pitch;
}
/// return kerning
inT16 kern() const {
return kerning;
}
/// return font class
inT16 font() const {
return font_class;
}
/// return spacing
inT16 space() const {
return spacing;
}
/// return filename
const char *name() const {
return filename.string ();
}
/// return xheight
inT32 x_height() const {
return xheight;
}
float cell_over_xheight() const {
return cell_over_xheight_;
}
void set_cell_over_xheight(float ratio) {
cell_over_xheight_ = ratio;
}
/// get rows
ROW_LIST *row_list() {
return &rows;
}
// Compute the margins between the edges of each row and this block's
// polyblock, and store the results in the rows.
void compute_row_margins();
// get paragraphs
PARA_LIST *para_list() {
return &paras_;
}
/// get blobs
C_BLOB_LIST *blob_list() {
return &c_blobs;
}
C_BLOB_LIST *reject_blobs() {
return &rej_blobs;
}
FCOORD re_rotation() const {
return re_rotation_; // How to transform coords back to image.
}
void set_re_rotation(const FCOORD& rotation) {
re_rotation_ = rotation;
}
FCOORD classify_rotation() const {
return classify_rotation_; // Apply this before classifying.
}
void set_classify_rotation(const FCOORD& rotation) {
classify_rotation_ = rotation;
}
FCOORD skew() const {
return skew_; // Direction of true horizontal.
}
void set_skew(const FCOORD& skew) {
skew_ = skew;
}
const ICOORD& median_size() const {
return median_size_;
}
void set_median_size(int x, int y) {
median_size_.set_x(x);
median_size_.set_y(y);
}
Pix* render_mask(TBOX* mask_box) {
return PDBLK::render_mask(re_rotation_, mask_box);
}
// Returns the bounding box including the desired combination of upper and
// lower noise/diacritic elements.
TBOX restricted_bounding_box(bool upper_dots, bool lower_dots) const;
// Reflects the polygon in the y-axis and recomputes the bounding_box.
// Does nothing to any contained rows/words/blobs etc.
void reflect_polygon_in_y_axis();
void rotate(const FCOORD& rotation);
/// decreasing y order
void sort_rows();
/// shrink white space
void compress();
/// check proportional
void check_pitch();
/// shrink white space and move by vector
void compress(const ICOORD vec);
/// dump whole table
void print(FILE *fp, BOOL8 dump);
BLOCK& operator=(const BLOCK & source);
private:
BOOL8 proportional; //< proportional
bool right_to_left_; //< major script is right to left.
inT8 kerning; //< inter blob gap
inT16 spacing; //< inter word gap
inT16 pitch; //< pitch of non-props
inT16 font_class; //< correct font class
inT32 xheight; //< height of chars
float cell_over_xheight_; //< Ratio of cell height to xheight.
STRING filename; //< name of block
ROW_LIST rows; //< rows in block
PARA_LIST paras_; //< paragraphs of block
C_BLOB_LIST c_blobs; //< before textord
C_BLOB_LIST rej_blobs; //< duff stuff
FCOORD re_rotation_; //< How to transform coords back to image.
FCOORD classify_rotation_; //< Apply this before classifying.
FCOORD skew_; //< Direction of true horizontal.
ICOORD median_size_; //< Median size of blobs.
};
int decreasing_top_order(const void *row1, const void *row2);
// A function to print segmentation stats for the given block list.
void PrintSegmentationStats(BLOCK_LIST* block_list);
// Extracts blobs fromo the given block list and adds them to the output list.
// The block list must have been created by performing a page segmentation.
void ExtractBlobsFromSegmentation(BLOCK_LIST* blocks,
C_BLOB_LIST* output_blob_list);
// Refreshes the words in the block_list by using blobs in the
// new_blobs list.
// Block list must have word segmentation in it.
// It consumes the blobs provided in the new_blobs list. The blobs leftover in
// the new_blobs list after the call weren't matched to any blobs of the words
// in block list.
// The output not_found_blobs is a list of blobs from the original segmentation
// in the block_list for which no corresponding new blobs were found.
void RefreshWordBlobsFromNewBlobs(BLOCK_LIST* block_list,
C_BLOB_LIST* new_blobs,
C_BLOB_LIST* not_found_blobs);
#endif