Creates and returns a Pix with the same resolution as the original in which 1 (black) pixels represent likely non text (photo, line drawing) areas of the page, deleting from the blob_block the blobs that were determined to be non-text. The photo_map is used to bias the decision towards non-text, rather than supplying definite decision. The blob_block is the usual result of connected component anal
| 84 | // holding the detected blobs. |
| 85 | // The returned Pix should be PixDestroyed after use. |
| 86 | Pix* CCNonTextDetect::ComputeNonTextMask(bool debug, Pix* photo_map, |
| 87 | TO_BLOCK* blob_block) { |
| 88 | // Insert the smallest blobs into the grid. |
| 89 | InsertBlobList(&blob_block->small_blobs); |
| 90 | InsertBlobList(&blob_block->noise_blobs); |
| 91 | // Add the medium blobs that don't have a good strokewidth neighbour. |
| 92 | // Those that do go into good_grid as an antidote to spreading beyond the |
| 93 | // real reaches of a noise region. |
| 94 | BlobGrid good_grid(gridsize(), bleft(), tright()); |
| 95 | BLOBNBOX_IT blob_it(&blob_block->blobs); |
| 96 | for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) { |
| 97 | BLOBNBOX* blob = blob_it.data(); |
| 98 | double perimeter_area_ratio = blob->cblob()->perimeter() / 4.0; |
| 99 | perimeter_area_ratio *= perimeter_area_ratio / blob->enclosed_area(); |
| 100 | if (blob->GoodTextBlob() == 0 || perimeter_area_ratio < kMinGoodTextPARatio) |
| 101 | InsertBBox(true, true, blob); |
| 102 | else |
| 103 | good_grid.InsertBBox(true, true, blob); |
| 104 | } |
| 105 | noise_density_ = ComputeNoiseDensity(debug, photo_map, &good_grid); |
| 106 | good_grid.Clear(); // Not needed any more. |
| 107 | Pix* pix = noise_density_->ThresholdToPix(max_noise_count_); |
| 108 | if (debug) { |
| 109 | pixWrite("junknoisemask.png", pix, IFF_PNG); |
| 110 | } |
| 111 | ScrollView* win = NULL; |
| 112 | #ifndef GRAPHICS_DISABLED |
| 113 | if (debug) { |
| 114 | win = MakeWindow(0, 400, "Photo Mask Blobs"); |
| 115 | } |
| 116 | #endif // GRAPHICS_DISABLED |
| 117 | // Large and medium blobs are not text if they overlap with "a lot" of small |
| 118 | // blobs. |
| 119 | MarkAndDeleteNonTextBlobs(&blob_block->large_blobs, |
| 120 | kMaxLargeOverlapsWithSmall, |
| 121 | win, ScrollView::DARK_GREEN, pix); |
| 122 | MarkAndDeleteNonTextBlobs(&blob_block->blobs, kMaxMediumOverlapsWithSmall, |
| 123 | win, ScrollView::WHITE, pix); |
| 124 | // Clear the grid of small blobs and insert the medium blobs. |
| 125 | Clear(); |
| 126 | InsertBlobList(&blob_block->blobs); |
| 127 | MarkAndDeleteNonTextBlobs(&blob_block->large_blobs, |
| 128 | kMaxLargeOverlapsWithMedium, |
| 129 | win, ScrollView::DARK_GREEN, pix); |
| 130 | // Clear again before we start deleting the blobs in the grid. |
| 131 | Clear(); |
| 132 | MarkAndDeleteNonTextBlobs(&blob_block->noise_blobs, -1, |
| 133 | win, ScrollView::CORAL, pix); |
| 134 | MarkAndDeleteNonTextBlobs(&blob_block->small_blobs, -1, |
| 135 | win, ScrollView::GOLDENROD, pix); |
| 136 | MarkAndDeleteNonTextBlobs(&blob_block->blobs, -1, |
| 137 | win, ScrollView::WHITE, pix); |
| 138 | if (debug) { |
| 139 | #ifndef GRAPHICS_DISABLED |
| 140 | win->Update(); |
| 141 | #endif // GRAPHICS_DISABLED |
| 142 | pixWrite("junkccphotomask.png", pix, IFF_PNG); |
| 143 | #ifndef GRAPHICS_DISABLED |
no test coverage detected