tesseract/textord/bbgrid.cpp

108 lines
4.1 KiB
C++
Raw Normal View History

///////////////////////////////////////////////////////////////////////
// File: bbgrid.cpp
// Description: Class to hold BLOBNBOXs in a grid for fast access
// to neighbours.
// Author: Ray Smith
// Created: Wed Jun 06 17:22:01 PDT 2007
//
// (C) Copyright 2007, Google Inc.
// 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.
//
///////////////////////////////////////////////////////////////////////
#include "bbgrid.h"
#include "ocrblock.h"
namespace tesseract {
#ifdef HAVE_LIBLEPT
// Make a Pix of the correct scaled size for the TraceOutline functions.
Pix* GridReducedPix(const TBOX& box, int gridsize,
ICOORD bleft, int* left, int* bottom) {
// Compute grid bounds of the outline and pad all round by 1.
int grid_left = (box.left() - bleft.x()) / gridsize - 1;
int grid_bottom = (box.bottom() - bleft.y()) / gridsize - 1;
int grid_right = (box.right() - bleft.x()) / gridsize + 1;
int grid_top = (box.top() - bleft.y()) / gridsize + 1;
*left = grid_left;
*bottom = grid_bottom;
return pixCreate(grid_right - grid_left + 1,
grid_top - grid_bottom + 1,
1);
}
// Helper function to return a scaled Pix with one pixel per grid cell,
// set (black) where the given outline enters the corresponding grid cell,
// and clear where the outline does not touch the grid cell.
// Also returns the grid coords of the bottom-left of the Pix, in *left
// and *bottom, which corresponds to (0, 0) on the Pix.
// Note that the Pix is used upside-down, with (0, 0) being the bottom-left.
Pix* TraceOutlineOnReducedPix(C_OUTLINE* outline, int gridsize,
ICOORD bleft, int* left, int* bottom) {
TBOX box = outline->bounding_box();
Pix* pix = GridReducedPix(box, gridsize, bleft, left, bottom);
int wpl = pixGetWpl(pix);
l_uint32* data = pixGetData(pix);
int length = outline->pathlength();
ICOORD pos = outline->start_pos();
for (int i = 0; i < length; ++i) {
int grid_x = (pos.x() - bleft.x()) / gridsize - *left;
int grid_y = (pos.y() - bleft.y()) / gridsize - *bottom;
SET_DATA_BIT(data + grid_y * wpl, grid_x);
pos += outline->step(i);
}
return pix;
}
#if 0 // Example code shows how to use TraceOutlineOnReducedPix.
C_OUTLINE_IT ol_it(blob->cblob()->out_list());
int grid_left, grid_bottom;
Pix* pix = TraceOutlineOnReducedPix(ol_it.data(), gridsize_, bleft_,
&grid_left, &grid_bottom);
grid->InsertPixPtBBox(grid_left, grid_bottom, pix, blob);
pixDestroy(&pix);
#endif
// As TraceOutlineOnReducedPix above, but on a BLOCK instead of a C_OUTLINE.
Pix* TraceBlockOnReducedPix(BLOCK* block, int gridsize,
ICOORD bleft, int* left, int* bottom) {
TBOX box = block->bounding_box();
Pix* pix = GridReducedPix(box, gridsize, bleft, left, bottom);
int wpl = pixGetWpl(pix);
l_uint32* data = pixGetData(pix);
ICOORDELT_IT it(block->poly_block()->points());
for (it.mark_cycle_pt(); !it.cycled_list();) {
ICOORD pos = *it.data();
it.forward();
ICOORD next_pos = *it.data();
ICOORD line_vector = next_pos - pos;
int major, minor;
ICOORD major_step, minor_step;
line_vector.setup_render(&major_step, &minor_step, &major, &minor);
int accumulator = major / 2;
while (pos != next_pos) {
int grid_x = (pos.x() - bleft.x()) / gridsize - *left;
int grid_y = (pos.y() - bleft.y()) / gridsize - *bottom;
SET_DATA_BIT(data + grid_y * wpl, grid_x);
pos += major_step;
accumulator += minor;
if (accumulator >= major) {
accumulator -= major;
pos += minor_step;
}
}
}
return pix;
}
#endif
} // namespace tesseract.