20# include "config_auto.h"
65 , noise_density_(nullptr) {
72 delete noise_density_;
92 BLOBNBOX_IT blob_it(&blob_block->
blobs);
93 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
96 perimeter_area_ratio *= perimeter_area_ratio / blob->
enclosed_area();
103 noise_density_ = ComputeNoiseDensity(debug, photo_map, &good_grid);
107 pixWrite(
"junknoisemask.png", pix, IFF_PNG);
110#ifndef GRAPHICS_DISABLED
132#ifndef GRAPHICS_DISABLED
135 pixWrite(
"junkccphotomask.png", pix, IFF_PNG);
136#ifndef GRAPHICS_DISABLED
151IntGrid *CCNonTextDetect::ComputeNoiseDensity(
bool debug,
Image photo_map,
BlobGrid *good_grid) {
159 int height = pixGetHeight(photo_map);
164 if (max_noise_count_ < noise + photo_offset && noise <= max_noise_count_) {
174 if (debug && noise > max_noise_count_ && good_counts->
GridCellValue(
x,
y) > 0) {
179 if (noise > max_noise_count_ && good_counts->
GridCellValue(
x,
y) > 0 &&
187 return noise_density;
193static TBOX AttemptBoxExpansion(
const TBOX &box,
const IntGrid &noise_density,
int pad) {
194 TBOX expanded_box(box);
195 expanded_box.set_right(box.right() + pad);
196 if (!noise_density.AnyZeroInRect(expanded_box)) {
200 expanded_box.set_left(box.left() - pad);
201 if (!noise_density.AnyZeroInRect(expanded_box)) {
205 expanded_box.set_top(box.top() + pad);
206 if (!noise_density.AnyZeroInRect(expanded_box)) {
210 expanded_box.set_bottom(box.bottom() + pad);
211 if (!noise_density.AnyZeroInRect(expanded_box)) {
216 if (!noise_density.AnyZeroInRect(expanded_box)) {
236void CCNonTextDetect::MarkAndDeleteNonTextBlobs(BLOBNBOX_LIST *blobs,
int max_blob_overlaps,
238 Image nontext_mask) {
240 BLOBNBOX_IT blob_it(blobs);
241 BLOBNBOX_LIST dead_blobs;
242 BLOBNBOX_IT dead_it(&dead_blobs);
243 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
244 BLOBNBOX *blob = blob_it.data();
245 TBOX box = blob->bounding_box();
247 (max_blob_overlaps < 0 || !BlobOverlapsTooMuch(blob, max_blob_overlaps))) {
248 blob->ClearNeighbours();
249#ifndef GRAPHICS_DISABLED
250 if (win !=
nullptr) {
251 blob->plot(win, ok_color, ok_color);
258 Image blob_pix = blob->cblob()->render_outline();
259 pixRasterop(nontext_mask, box.left(), imageheight - box.top(), box.width(), box.height(),
260 PIX_SRC | PIX_DST, blob_pix, 0, 0);
267 box = AttemptBoxExpansion(box, *noise_density_,
gridsize());
270 pixRasterop(nontext_mask, box.left(), imageheight - box.top(), box.width(), box.height(),
271 PIX_SET,
nullptr, 0, 0);
273#ifndef GRAPHICS_DISABLED
274 if (win !=
nullptr) {
282 delete blob->remove_cblob();
283 dead_it.add_to_end(blob_it.extract());
290bool CCNonTextDetect::BlobOverlapsTooMuch(BLOBNBOX *blob,
int max_overlaps) {
294 const TBOX &box = blob->bounding_box();
295 rsearch.StartRectSearch(box);
296 rsearch.SetUniqueMode(
true);
298 int overlap_count = 0;
299 while (overlap_count <= max_overlaps && (neighbour = rsearch.NextRectSearch()) !=
nullptr) {
300 if (box.major_overlap(neighbour->bounding_box())) {
302 if (overlap_count > max_overlaps) {
const double kMinGoodTextPARatio
const int kMaxMediumOverlapsWithSmall
const int kOriginalNoiseMultiple
const int kMaxLargeOverlapsWithMedium
const int kMaxLargeOverlapsWithSmall
void tprintf(const char *format,...)
int IntCastRounded(double x)
const double kMaxSmallNeighboursPerPix
const double kPhotoOffsetFraction
GridSearch< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > BlobGridSearch
int32_t enclosed_area() const
BLOBNBOX_LIST small_blobs
BLOBNBOX_LIST large_blobs
BLOBNBOX_LIST noise_blobs
TDimension y() const
access_function
TDimension x() const
access function
const ICOORD & bleft() const
const ICOORD & tright() const
IntGrid * NeighbourhoodSum() const
int GridCellValue(int grid_x, int grid_y) const
bool RectMostlyOverThreshold(const TBOX &rect, int threshold) const
Image ThresholdToPix(int threshold) const
void SetGridCell(int grid_x, int grid_y, int value)
bool AnyZeroInRect(const TBOX &rect) const
IntGrid * CountCellElements()
void InsertBBox(bool h_spread, bool v_spread, BLOBNBOX *bbox)
ScrollView * MakeWindow(int x, int y, const char *window_name)
void InsertBlobList(BLOBNBOX_LIST *blobs)
CCNonTextDetect(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Image ComputeNonTextMask(bool debug, Image photo_map, TO_BLOCK *blob_block)
~CCNonTextDetect() override
static bool BoundsWithinRect(Image pix, int *x_start, int *y_start, int *x_end, int *y_end)
std::unique_ptr< SVEvent > AwaitEvent(SVEventType type)