src/textord/imagefind.cpp
static bool pixNearlyRectangular(Image pix, double min_fraction, double max_fraction,
                                 double max_skew_gradient, int *x_start, int *y_start,
                                 int *x_end, int *y_end) {
  ASSERT_HOST(pix != nullptr);
  *x_start = 0;
  *x_end = pixGetWidth(pix);
  *y_start = 0;
  *y_end = pixGetHeight(pix);

  uint32_t *data = pixGetData(pix);
  int wpl = pixGetWpl(pix);
  bool any_cut = false;
  bool left_done = false;
  bool right_done = false;
  bool top_done = false;
  bool bottom_done = false;
  do {
    any_cut = false;
    // Find the top/bottom edges.
    int width = *x_end - *x_start;
    int min_count = static_cast<int>(width * min_fraction);
    int max_count = static_cast<int>(width * max_fraction);
    int edge_width = static_cast<int>(width * max_skew_gradient);
    if (HScanForEdge(data, wpl, *x_start, *x_end, min_count, edge_width, max_count, *y_end, 1,
                     y_start) &&
        !top_done) {
      top_done = true;
      any_cut = true;
    }
    --(*y_end);
    if (HScanForEdge(data, wpl, *x_start, *x_end, min_count, edge_width, max_count, *y_start, -1,
                     y_end) &&
        !bottom_done) {
      bottom_done = true;
      any_cut = true;
    }
    ++(*y_end);

    // Find the left/right edges.
    int height = *y_end - *y_start;
    min_count = static_cast<int>(height * min_fraction);
    max_count = static_cast<int>(height * max_fraction);
    edge_width = static_cast<int>(height * max_skew_gradient);
    if (VScanForEdge(data, wpl, *y_start, *y_end, min_count, edge_width, max_count, *x_end, 1,
                     x_start) &&
        !left_done) {
      left_done = true;
      any_cut = true;
    }
    --(*x_end);
    if (VScanForEdge(data, wpl, *y_start, *y_end, min_count, edge_width, max_count, *x_start, -1,
                     x_end) &&
        !right_done) {
      right_done = true;
      any_cut = true;
    }
    ++(*x_end);
  } while (any_cut);

  // All edges must satisfy the condition of sharp gradient in pixel density
  // in order for the full rectangle to be present.
  return left_done && right_done && top_done && bottom_done;
}
// Returns true if there is a rectangle in the source pix, such that all
// pixel rows and column slices outside of it have less than
// min_fraction of the pixels black, and within max_skew_gradient fraction
// of the pixels on the inside, there are at least max_fraction of the
// pixels black. In other words, the inside of the rectangle looks roughly
// rectangular, and the outside of it looks like extra bits.
// On return, the rectangle is defined by x_start, y_start, x_end and y_end.
// Note: the algorithm is iterative, allowing it to slice off pixels from
// one edge, allowing it to then slice off more pixels from another edge.
Returns true if there is a rectangle in the source pix, such that all
pixel rows and column slices outside of it have less than
min_fraction of the pixels black, and within max_skew_gradient fraction
of the pixels on the inside, there are at least max_fraction of the
pixels black. In other words, the inside of the rectangle looks roughly
rectangular, and the outside of it looks like extra bits.
Returns true if there is a rectangle in the source pix such that all pixel rows and column slices outside of it have less than min_fraction of the pixels black and within max_skew_gradient fraction of the pixels on the inside there are at least max_fraction of the pixels black . In other words the inside of the rectangle looks roughly rectangular and the outside of it looks like extra bits .
static bool pixNearlyRectangular(Image pix, double min_fraction, double max_fraction,
                                 double max_skew_gradient, int *x_start, int *y_start,
                                 int *x_end, int *y_end) {
  ASSERT_HOST(pix != nullptr);
  *x_start = 0;
  *x_end = pixGetWidth(pix);
  *y_start = 0;
  *y_end = pixGetHeight(pix);
  uint32_t *data = pixGetData(pix);
  int wpl = pixGetWpl(pix);
  bool any_cut = false;
  bool left_done = false;
  bool right_done = false;
  bool top_done = false;
  bool bottom_done = false;
  do {
    any_cut = false;
    int width = *x_end - *x_start;
    int min_count = static_cast<int>(width * min_fraction);
    int max_count = static_cast<int>(width * max_fraction);
    int edge_width = static_cast<int>(width * max_skew_gradient);
    if (HScanForEdge(data, wpl, *x_start, *x_end, min_count, edge_width, max_count, *y_end, 1,
                     y_start) &&
        !top_done) {
      top_done = true;
      any_cut = true;
    }
    --(*y_end);
    if (HScanForEdge(data, wpl, *x_start, *x_end, min_count, edge_width, max_count, *y_start, -1,
                     y_end) &&
        !bottom_done) {
      bottom_done = true;
      any_cut = true;
    }
    ++(*y_end);
    int height = *y_end - *y_start;
    min_count = static_cast<int>(height * min_fraction);
    max_count = static_cast<int>(height * max_fraction);
    edge_width = static_cast<int>(height * max_skew_gradient);
    if (VScanForEdge(data, wpl, *y_start, *y_end, min_count, edge_width, max_count, *x_end, 1,
                     x_start) &&
        !left_done) {
      left_done = true;
      any_cut = true;
    }
    --(*x_end);
    if (VScanForEdge(data, wpl, *y_start, *y_end, min_count, edge_width, max_count, *x_start, -1,
                     x_end) &&
        !right_done) {
      right_done = true;
      any_cut = true;
    }
    ++(*x_end);
  } while (any_cut);
  return left_done && right_done && top_done && bottom_done;
}
static bool pixNearlyRectangular ( Image pix , double min_fraction , double max_fraction , double max_skew_gradient , int * x_start , int * y_start , int * x_end , int * y_end ) { ASSERT_HOST ( pix != nullptr ) ; * x_start = 0 ; * x_end = pixGetWidth ( pix ) ; * y_start = 0 ; * y_end = pixGetHeight ( pix ) ; uint32_t * data = pixGetData ( pix ) ; int wpl = pixGetWpl ( pix ) ; bool any_cut = false ; bool left_done = false ; bool right_done = false ; bool top_done = false ; bool bottom_done = false ; do { any_cut = false ; int width = * x_end - * x_start ; int min_count = static_cast < int > ( width * min_fraction ) ; int max_count = static_cast < int > ( width * max_fraction ) ; int edge_width = static_cast < int > ( width * max_skew_gradient ) ; if ( HScanForEdge ( data , wpl , * x_start , * x_end , min_count , edge_width , max_count , * y_end , 1 , y_start ) && ! top_done ) { top_done = true ; any_cut = true ; } -- ( * y_end ) ; if ( HScanForEdge ( data , wpl , * x_start , * x_end , min_count , edge_width , max_count , * y_start , -1 , y_end ) && ! bottom_done ) { bottom_done = true ; any_cut = true ; } ++ ( * y_end ) ; int height = * y_end - * y_start ; min_count = static_cast < int > ( height * min_fraction ) ; max_count = static_cast < int > ( height * max_fraction ) ; edge_width = static_cast < int > ( height * max_skew_gradient ) ; if ( VScanForEdge ( data , wpl , * y_start , * y_end , min_count , edge_width , max_count , * x_end , 1 , x_start ) && ! left_done ) { left_done = true ; any_cut = true ; } -- ( * x_end ) ; if ( VScanForEdge ( data , wpl , * y_start , * y_end , min_count , edge_width , max_count , * x_start , -1 , x_end ) && ! right_done ) { right_done = true ; any_cut = true ; } ++ ( * x_end ) ; } while ( any_cut ) ; return left_done && right_done && top_done && bottom_done ; }
Returns true if there is a rectangle in the source pix, such that all
pixel rows and column slices outside of it have less than
min_fraction of the pixels black, and within max_skew_gradient fraction
of the pixels on the inside, there are at least max_fraction of the
pixels black.
Returns true if there is a rectangle in the source pix such that all pixel rows and column slices outside of it have less than min_fraction of the pixels black and within max_skew_gradient fraction of the pixels on the inside there are at least max_fraction of the pixels black .
// Find the top/bottom edges. // Find the left/right edges. // All edges must satisfy the condition of sharp gradient in pixel density // in order for the full rectangle to be present.