src/textord/colpartitiongrid.cpp
bool ColPartitionGrid::SmoothRegionType(Image nontext_map, const TBOX &im_box,
                                        const FCOORD &rerotation, bool debug,
                                        ColPartition *part) {
  const TBOX &part_box = part->bounding_box();
  if (debug) {
    tprintf("Smooothing part at:");
    part_box.print();
  }
  BlobRegionType best_type = BRT_UNKNOWN;
  int best_dist = INT32_MAX;
  int max_dist = std::min(part_box.width(), part_box.height());
  max_dist = std::max(max_dist * kMaxNeighbourDistFactor, gridsize() * 2);
  // Search with the pad truncated on each side of the box in turn.
  bool any_image = false;
  bool all_image = true;
  for (int d = 0; d < BND_COUNT; ++d) {
    int dist;
    auto dir = static_cast<BlobNeighbourDir>(d);
    BlobRegionType type = SmoothInOneDirection(dir, nontext_map, im_box,
                                               rerotation, debug, *part, &dist);
    if (debug) {
      tprintf("Result in dir %d = %d at dist %d\n", dir, type, dist);
    }
    if (type != BRT_UNKNOWN && dist < best_dist) {
      best_dist = dist;
      best_type = type;
    }
    if (type == BRT_POLYIMAGE) {
      any_image = true;
    } else {
      all_image = false;
    }
  }
  if (best_dist > max_dist) {
    return false; // Too far away to set the type with it.
  }
  if (part->flow() == BTFT_STRONG_CHAIN && !all_image) {
    return false; // We are not modifying it.
  }
  BlobRegionType new_type = part->blob_type();
  BlobTextFlowType new_flow = part->flow();
  if (best_type == BRT_TEXT && !any_image) {
    new_flow = BTFT_STRONG_CHAIN;
    new_type = BRT_TEXT;
  } else if (best_type == BRT_VERT_TEXT && !any_image) {
    new_flow = BTFT_STRONG_CHAIN;
    new_type = BRT_VERT_TEXT;
  } else if (best_type == BRT_POLYIMAGE) {
    new_flow = BTFT_NONTEXT;
    new_type = BRT_UNKNOWN;
  }
  if (new_type != part->blob_type() || new_flow != part->flow()) {
    part->set_flow(new_flow);
    part->set_blob_type(new_type);
    part->SetBlobTypes();
    if (debug) {
      tprintf("Modified part:");
      part->Print();
    }
    return true;
  } else {
    return false;
  }
}
// Smoothes the region type/flow type of the given part by looking at local
// neighbours and the given image mask. Searches a padded rectangle with the
// padding truncated on one size of the part's box in turn for each side,
// using the result (if any) that has the least distance to all neighbours
// that contribute to the decision. This biases in favor of rectangular
// regions without completely enforcing them.
// If a good decision cannot be reached, the part is left unchanged.
// im_box and rerotation are used to map blob coordinates onto the
// nontext_map, which is used to prevent the spread of text neighbourhoods
// into images.
// Returns true if the partition was changed.
Smoothes the region type/flow type of the given part by looking at local
neighbours and the given image mask. Searches a padded rectangle with the
padding truncated on one size of the part's box in turn for each side,
using the result (if any) that has the least distance to all neighbours
that contribute to the decision. This biases in favor of rectangular
regions without completely enforcing them.
If a good decision cannot be reached, the part is left unchanged.
im_box and rerotation are used to map blob coordinates onto the
nontext_map, which is used to prevent the spread of text neighbourhoods
into images.
Returns true if the partition was changed.
Smoothes the region type / flow type of the given part by looking at local neighbours and the given image mask . Searches a padded rectangle with the padding truncated on one size of the part ' s box in turn for each side using the result ( if any ) that has the least distance to all neighbours that contribute to the decision . This biases in favor of rectangular regions without completely enforcing them . If a good decision cannot be reached the part is left unchanged . im_box and rerotation are used to map blob coordinates onto the nontext_map which is used to prevent the spread of text neighbourhoods into images . Returns true if the partition was changed .
bool ColPartitionGrid::SmoothRegionType(Image nontext_map, const TBOX &im_box,
                                        const FCOORD &rerotation, bool debug,
                                        ColPartition *part) {
  const TBOX &part_box = part->bounding_box();
  if (debug) {
    tprintf("Smooothing part at:");
    part_box.print();
  }
  BlobRegionType best_type = BRT_UNKNOWN;
  int best_dist = INT32_MAX;
  int max_dist = std::min(part_box.width(), part_box.height());
  max_dist = std::max(max_dist * kMaxNeighbourDistFactor, gridsize() * 2);
  bool any_image = false;
  bool all_image = true;
  for (int d = 0; d < BND_COUNT; ++d) {
    int dist;
    auto dir = static_cast<BlobNeighbourDir>(d);
    BlobRegionType type = SmoothInOneDirection(dir, nontext_map, im_box,
                                               rerotation, debug, *part, &dist);
    if (debug) {
      tprintf("Result in dir %d = %d at dist %d\n", dir, type, dist);
    }
    if (type != BRT_UNKNOWN && dist < best_dist) {
      best_dist = dist;
      best_type = type;
    }
    if (type == BRT_POLYIMAGE) {
      any_image = true;
    } else {
      all_image = false;
    }
  }
  if (best_dist > max_dist) {
    return false; 
  }
  if (part->flow() == BTFT_STRONG_CHAIN && !all_image) {
    return false; 
  }
  BlobRegionType new_type = part->blob_type();
  BlobTextFlowType new_flow = part->flow();
  if (best_type == BRT_TEXT && !any_image) {
    new_flow = BTFT_STRONG_CHAIN;
    new_type = BRT_TEXT;
  } else if (best_type == BRT_VERT_TEXT && !any_image) {
    new_flow = BTFT_STRONG_CHAIN;
    new_type = BRT_VERT_TEXT;
  } else if (best_type == BRT_POLYIMAGE) {
    new_flow = BTFT_NONTEXT;
    new_type = BRT_UNKNOWN;
  }
  if (new_type != part->blob_type() || new_flow != part->flow()) {
    part->set_flow(new_flow);
    part->set_blob_type(new_type);
    part->SetBlobTypes();
    if (debug) {
      tprintf("Modified part:");
      part->Print();
    }
    return true;
  } else {
    return false;
  }
}
bool ColPartitionGrid :: SmoothRegionType ( Image nontext_map , const TBOX & im_box , const FCOORD & rerotation , bool debug , ColPartition * part ) { const TBOX & part_box = part -> bounding_box ( ) ; if ( debug ) { tprintf ( " " ) ; part_box . print ( ) ; } BlobRegionType best_type = BRT_UNKNOWN ; int best_dist = INT32_MAX ; int max_dist = std :: min ( part_box . width ( ) , part_box . height ( ) ) ; max_dist = std :: max ( max_dist * kMaxNeighbourDistFactor , gridsize ( ) * 2 ) ; bool any_image = false ; bool all_image = true ; for ( int d = 0 ; d < BND_COUNT ; ++ d ) { int dist ; auto dir = static_cast < BlobNeighbourDir > ( d ) ; BlobRegionType type = SmoothInOneDirection ( dir , nontext_map , im_box , rerotation , debug , * part , & dist ) ; if ( debug ) { tprintf ( " \n " , dir , type , dist ) ; } if ( type != BRT_UNKNOWN && dist < best_dist ) { best_dist = dist ; best_type = type ; } if ( type == BRT_POLYIMAGE ) { any_image = true ; } else { all_image = false ; } } if ( best_dist > max_dist ) { return false ; } if ( part -> flow ( ) == BTFT_STRONG_CHAIN && ! all_image ) { return false ; } BlobRegionType new_type = part -> blob_type ( ) ; BlobTextFlowType new_flow = part -> flow ( ) ; if ( best_type == BRT_TEXT && ! any_image ) { new_flow = BTFT_STRONG_CHAIN ; new_type = BRT_TEXT ; } else if ( best_type == BRT_VERT_TEXT && ! any_image ) { new_flow = BTFT_STRONG_CHAIN ; new_type = BRT_VERT_TEXT ; } else if ( best_type == BRT_POLYIMAGE ) { new_flow = BTFT_NONTEXT ; new_type = BRT_UNKNOWN ; } if ( new_type != part -> blob_type ( ) || new_flow != part -> flow ( ) ) { part -> set_flow ( new_flow ) ; part -> set_blob_type ( new_type ) ; part -> SetBlobTypes ( ) ; if ( debug ) { tprintf ( " " ) ; part -> Print ( ) ; } return true ; } else { return false ; } }
Smoothes the region type/flow type of the given part by looking at local
neighbours and the given image mask.
Smoothes the region type / flow type of the given part by looking at local neighbours and the given image mask .
// Search with the pad truncated on each side of the box in turn. // Too far away to set the type with it. // We are not modifying it.