21 #include "config_auto.h" 66 gridsize * gridsize)),
67 noise_density_(nullptr) {
74 delete noise_density_;
95 BLOBNBOX_IT blob_it(&blob_block->
blobs);
96 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
99 perimeter_area_ratio *= perimeter_area_ratio / blob->
enclosed_area();
105 noise_density_ = ComputeNoiseDensity(debug, photo_map, &good_grid);
109 pixWrite(
"junknoisemask.png", pix, IFF_PNG);
112 #ifndef GRAPHICS_DISABLED 116 #endif // GRAPHICS_DISABLED 119 MarkAndDeleteNonTextBlobs(&blob_block->
large_blobs,
127 MarkAndDeleteNonTextBlobs(&blob_block->
large_blobs,
132 MarkAndDeleteNonTextBlobs(&blob_block->
noise_blobs, -1,
134 MarkAndDeleteNonTextBlobs(&blob_block->
small_blobs, -1,
136 MarkAndDeleteNonTextBlobs(&blob_block->
blobs, -1,
139 #ifndef GRAPHICS_DISABLED 141 #endif // GRAPHICS_DISABLED 142 pixWrite(
"junkccphotomask.png", pix, IFF_PNG);
143 #ifndef GRAPHICS_DISABLED 146 #endif // GRAPHICS_DISABLED 158 IntGrid* CCNonTextDetect::ComputeNoiseDensity(
bool debug, Pix* photo_map,
167 int height = pixGetHeight(photo_map);
172 if (max_noise_count_ < noise + photo_offset &&
173 noise <= max_noise_count_) {
177 int bottom = height - y *
gridsize();
181 noise_density->
SetGridCell(x, y, noise + photo_offset);
184 if (debug && noise > max_noise_count_ &&
186 tprintf(
"At %d, %d, noise = %d, good=%d, orig=%d, thr=%d\n",
192 if (noise > max_noise_count_ &&
202 return noise_density;
208 static TBOX AttemptBoxExpansion(
const TBOX& box,
const IntGrid& noise_density,
210 TBOX expanded_box(box);
211 expanded_box.set_right(box.
right() + pad);
212 if (!noise_density.AnyZeroInRect(expanded_box))
216 if (!noise_density.AnyZeroInRect(expanded_box))
220 if (!noise_density.AnyZeroInRect(expanded_box))
224 if (!noise_density.AnyZeroInRect(expanded_box))
228 if (!noise_density.AnyZeroInRect(expanded_box))
247 void CCNonTextDetect::MarkAndDeleteNonTextBlobs(BLOBNBOX_LIST* blobs,
248 int max_blob_overlaps,
253 BLOBNBOX_IT blob_it(blobs);
254 BLOBNBOX_LIST dead_blobs;
255 BLOBNBOX_IT dead_it(&dead_blobs);
256 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
260 (max_blob_overlaps < 0 ||
261 !BlobOverlapsTooMuch(blob, max_blob_overlaps))) {
263 #ifndef GRAPHICS_DISABLED 265 blob->
plot(win, ok_color, ok_color);
266 #endif // GRAPHICS_DISABLED 272 pixRasterop(nontext_mask, box.
left(), imageheight - box.
top(),
275 pixDestroy(&blob_pix);
281 box = AttemptBoxExpansion(box, *noise_density_,
gridsize());
284 pixRasterop(nontext_mask, box.
left(), imageheight - box.
top(),
285 box.
width(), box.
height(), PIX_SET,
nullptr, 0, 0);
287 #ifndef GRAPHICS_DISABLED 290 #endif // GRAPHICS_DISABLED 296 delete blob->
cblob();
297 dead_it.add_to_end(blob_it.extract());
304 bool CCNonTextDetect::BlobOverlapsTooMuch(
BLOBNBOX* blob,
int max_overlaps) {
309 rsearch.StartRectSearch(box);
310 rsearch.SetUniqueMode(
true);
312 int overlap_count = 0;
313 while (overlap_count <= max_overlaps &&
314 (neighbour = rsearch.NextRectSearch()) !=
nullptr) {
317 if (overlap_count > max_overlaps)
const int kMaxLargeOverlapsWithMedium
void InsertBlobList(BLOBNBOX_LIST *blobs)
ScrollView * MakeWindow(int x, int y, const char *window_name)
const ICOORD & bleft() const
CCNonTextDetect(int gridsize, const ICOORD &bleft, const ICOORD &tright)
int16_t y() const
access_function
const int kMaxMediumOverlapsWithSmall
int32_t enclosed_area() const
void plot(ScrollView *window, ScrollView::Color blob_colour, ScrollView::Color child_colour)
const double kMinGoodTextPARatio
int GridCellValue(int grid_x, int grid_y) const
SVEvent * AwaitEvent(SVEventType type)
bool AnyZeroInRect(const TBOX &rect) const
const int kMaxLargeOverlapsWithSmall
int16_t x() const
access function
const int kOriginalNoiseMultiple
bool RectMostlyOverThreshold(const TBOX &rect, int threshold) const
bool major_overlap(const TBOX &box) const
int IntCastRounded(double x)
void InsertBBox(bool h_spread, bool v_spread, BLOBNBOX *bbox)
GridSearch< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > BlobGridSearch
DLLSYM void tprintf(const char *format,...)
void SetGridCell(int grid_x, int grid_y, int value)
const double kPhotoOffsetFraction
IntGrid * CountCellElements()
IntGrid * NeighbourhoodSum() const
virtual ~CCNonTextDetect()
const TBOX & bounding_box() const
static bool BoundsWithinRect(Pix *pix, int *x_start, int *y_start, int *x_end, int *y_end)
BLOBNBOX_LIST large_blobs
Pix * ComputeNonTextMask(bool debug, Pix *photo_map, TO_BLOCK *blob_block)
void pad(int xpad, int ypad)
const double kMaxSmallNeighboursPerPix
Pix * ThresholdToPix(int threshold) const
const ICOORD & tright() const
BLOBNBOX_LIST small_blobs
BLOBNBOX_LIST noise_blobs