62 gridsize * gridsize)),
63 noise_density_(
NULL) {
70 delete noise_density_;
91 BLOBNBOX_IT blob_it(&blob_block->
blobs);
92 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
95 perimeter_area_ratio *= perimeter_area_ratio / blob->
enclosed_area();
101 noise_density_ = ComputeNoiseDensity(debug, photo_map, &good_grid);
105 pixWrite(
"junknoisemask.png", pix, IFF_PNG);
108 #ifndef GRAPHICS_DISABLED
112 #endif // GRAPHICS_DISABLED
115 MarkAndDeleteNonTextBlobs(&blob_block->
large_blobs,
123 MarkAndDeleteNonTextBlobs(&blob_block->
large_blobs,
128 MarkAndDeleteNonTextBlobs(&blob_block->
noise_blobs, -1,
130 MarkAndDeleteNonTextBlobs(&blob_block->
small_blobs, -1,
132 MarkAndDeleteNonTextBlobs(&blob_block->
blobs, -1,
135 #ifndef GRAPHICS_DISABLED
137 #endif // GRAPHICS_DISABLED
138 pixWrite(
"junkccphotomask.png", pix, IFF_PNG);
139 #ifndef GRAPHICS_DISABLED
142 #endif // GRAPHICS_DISABLED
154 IntGrid* CCNonTextDetect::ComputeNoiseDensity(
bool debug, Pix* photo_map,
163 int height = pixGetHeight(photo_map);
168 if (max_noise_count_ < noise + photo_offset &&
169 noise <= max_noise_count_) {
173 int bottom = height - y *
gridsize();
177 noise_density->
SetGridCell(x, y, noise + photo_offset);
180 if (debug && noise > max_noise_count_ &&
182 tprintf(
"At %d, %d, noise = %d, good=%d, orig=%d, thr=%d\n",
188 if (noise > max_noise_count_ &&
198 return noise_density;
204 static TBOX AttemptBoxExpansion(
const TBOX& box,
const IntGrid& noise_density,
206 TBOX expanded_box(box);
207 expanded_box.set_right(box.
right() + pad);
208 if (!noise_density.AnyZeroInRect(expanded_box))
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))
243 void CCNonTextDetect::MarkAndDeleteNonTextBlobs(BLOBNBOX_LIST* blobs,
244 int max_blob_overlaps,
249 BLOBNBOX_IT blob_it(blobs);
250 BLOBNBOX_LIST dead_blobs;
251 BLOBNBOX_IT dead_it(&dead_blobs);
252 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
256 (max_blob_overlaps < 0 ||
257 !BlobOverlapsTooMuch(blob, max_blob_overlaps))) {
259 #ifndef GRAPHICS_DISABLED
261 blob->
plot(win, ok_color, ok_color);
262 #endif // GRAPHICS_DISABLED
268 pixRasterop(nontext_mask, box.
left(), imageheight - box.
top(),
271 pixDestroy(&blob_pix);
277 box = AttemptBoxExpansion(box, *noise_density_,
gridsize());
280 pixRasterop(nontext_mask, box.
left(), imageheight - box.
top(),
283 #ifndef GRAPHICS_DISABLED
286 #endif // GRAPHICS_DISABLED
292 delete blob->
cblob();
293 dead_it.add_to_end(blob_it.extract());
300 bool CCNonTextDetect::BlobOverlapsTooMuch(
BLOBNBOX* blob,
int max_overlaps) {
305 rsearch.StartRectSearch(box);
306 rsearch.SetUniqueMode(
true);
308 int overlap_count = 0;
309 while (overlap_count <= max_overlaps &&
310 (neighbour = rsearch.NextRectSearch()) !=
NULL) {
313 if (overlap_count > max_overlaps)
BLOBNBOX_LIST noise_blobs
int IntCastRounded(double x)
inT32 enclosed_area() const
inT16 x() const
access function
const TBOX & bounding_box() const
const double kMaxSmallNeighboursPerPix
const int kMaxLargeOverlapsWithMedium
static bool BoundsWithinRect(Pix *pix, int *x_start, int *y_start, int *x_end, int *y_end)
GridSearch< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > BlobGridSearch
const double kPhotoOffsetFraction
virtual ~CCNonTextDetect()
inT16 y() const
access_function
const int kMaxMediumOverlapsWithSmall
const int kOriginalNoiseMultiple
bool RectMostlyOverThreshold(const TBOX &rect, int threshold) const
IntGrid * CountCellElements()
const double kMinGoodTextPARatio
Pix * ThresholdToPix(int threshold) const
int GridCellValue(int grid_x, int grid_y) const
BLOBNBOX_LIST small_blobs
void plot(ScrollView *window, ScrollView::Color blob_colour, ScrollView::Color child_colour)
bool AnyZeroInRect(const TBOX &rect) const
DLLSYM void tprintf(const char *format,...)
Pix * ComputeNonTextMask(bool debug, Pix *photo_map, TO_BLOCK *blob_block)
void InsertBlobList(BLOBNBOX_LIST *blobs)
const ICOORD & tright() const
void InsertBBox(bool h_spread, bool v_spread, BLOBNBOX *bbox)
bool major_overlap(const TBOX &box) const
BLOBNBOX_LIST large_blobs
void pad(int xpad, int ypad)
const ICOORD & bleft() const
IntGrid * NeighbourhoodSum() const
void SetGridCell(int grid_x, int grid_y, int value)
CCNonTextDetect(int gridsize, const ICOORD &bleft, const ICOORD &tright)
ScrollView * MakeWindow(int x, int y, const char *window_name)
const int kMaxLargeOverlapsWithSmall