1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
<!--
SPDX-FileCopyrightText: 2005 The unpaper authors
SPDX-License-Identifier: GPL-2.0-only
-->
Image Processing Features
=========================
## Blackfilter
Sometimes it is desirable to automatically remove large black areas
which originate from bad photocopies or other optical influences. The
**blackfilter** can help to find large areas of black and wipe them
out automatically.

Be careful with pictures in scanned documents, especially with
diagrams. Some diagrams intentionally contain large areas of dark
color, which might be affected by automatic wipe-out of the
*blackfilter*. In order to prevent actual *page* content from being
wiped out, the option `--blackfilter-scan-exclude` allows to specify
areas on the *sheet* which should not be taken into account by the
*blackfilter*. When using one of the default *layout templates* set
via the `--layout` option, the inner area of each *page* will
automatically be excluded from black-filtering.

The *blackfilter* can be disabled by the option `--no-blackfilter`,
optionally followed by the *sheet* numbers to disable the filter for.
## Noisefilter
The **noisefilter** removes small clusters of pixels ("noise") from
the *sheet*. The maximum pixel-size of clusters to be removed can be
set via `--noisefilter-intensity`. This value must not be chosen too
high in order not to remove relevant elements of *page* content,
e.g. normal text-points ("."). As a consequence, this option might
have to be adjusted on images with a low scan resolution.

Disable with `--no-noisefilter`, optionally followed by the *sheet*
numbers to disable the filter for.
## Blurfilter
The **blurfilter** removes "lonely" clusters of pixels, i.e. clusters
which have only very few other dark pixels in their neighborhood.

The size of the neighborhood to be searched and the amount of other
dark pixels accepted in the neighborhood below which the area gets
wiped out can be adjusted with the options `--blurfilter-size`,
`--blurfilter-step` and `--blurfilter-intensity`. Additionally,
`--blurfilter-step` also determines the step-size with which the
neighborhood-area is moved across the image while filtering.

Disable with `--no-blurfilter`, optionally followed by the *sheet*
numbers to disable the filter for.
## Grayfilter
The **grayfilter** removes areas which are gray-only, that means it
wipes out all those areas which do not contain a maximum relative
amount of non-dark pixels. The size of the local area the *grayfilter*
operates on can be set using `--grayfilter-size`, and the granularity
of detection is controlled via `--grayfilter-step`. The maximum
relative amount of non-dark pixels that are still considered to be
deletable can be set using `--grayfilter-threshold`.
Be careful with the *grayfilter* when processing color scans, because
any bright color might be considered as gray and be wiped out. It
might be a good idea to disable the *grayfilter* when processing color
scans.
Disable with `--no-grayfilter`, optionally followed by the *sheet*
numbers to disable the filter for.
## Deskewing (Auto-Straightening)
The *deskewing* performed by `unpaper` is actually a rotation to
automatically straighten rectangular content areas on the *sheet*. It
is applied to any *mask* that has been found during *mask-detection*
or that has been set directly via the `--mask` option.

The algorithm that detects the angle of skew works better the more
regular and solid the edges of the area's content are. It works as
follows: A 'virtual line' is moved from the outside of one edge inside
the rectangular area. This happens several times, gradually changing
the rotation of the 'virtual line'. (Called 'virtual', because there
is of course no visible line drawn in the image.) The algorithm will
count the number of dark pixels along the line as it is virtually
moved.
Some parameters control the size of the 'virtual line' and its
movement: `--deskew-scan-size`: the height/width of the 'virtual line'
used for scanning (the length of the line at rotation angle 0)
`--deskew-scan-range`: the absolute value of degrees between the
negative and positive value of which the line will be rotated (i.e.,
the default value 5.0 will cause the 'virtual line' to be rotated in
several small steps between -5.0 degrees and 5.0 degrees).
`--deskew-scan-step`: the step size with which to iterate between the
bounds set by `--deskew-scan-range` (I.e., a value of 0.1 will lead to
the virtual line being successively rotated with
0.0, 0.1, -0.1, 0.2, -0.2, 0.3, -0.3 ... degrees.)

At each of these rotation steps, the following is done: The rotated
'virtual line' gets moved (again 'moved virtually') towards the center
of the rectangular area on which detection gets performed. Movement
is performed pixel by pixel, it starts with the line completely
outside the rectangular area, not yet reaching inside the area. At
each movement-step, the number of dark pixels covered by the virtual
line is counted and is accumulated as the total sum of dark
pixels. For each rotation angle at which this is done, the maximum
difference in the accumulated sum of dark pixels occurring between a
previous movement-step and the next one gets calculated. The rotation
angle for which this maximum difference becomes maximal will be the
rotation angle detected for *deskewing*.
The relative amount of dark pixels to accumulate before shifting the
'virtual line' is stopped (and continued with the next rotation-step)
is given by `--deskew-scan-depth`. This value is relative to the
number of pixels that the 'virtual line' covers in total, i.e. for
the default deskew-scan-size of 1500 and the default deskew-scan-depth
of 0.66, shifting at each rotation step stops after 1000 dark pixels
have been counted in sum (or, if not enough pixels are met, when the
'virtual line' has reached the center of the rectangular area).
Sometimes, trying out different deskew-scan-depth values, either lower
than the default of 0.66, or higher, can noticeably increase detection
quality. Which value is best is merely coincidental, depending on the
shape of the outer edges of each very first character in each line of
a text area.

The above described the detection process starting at one single edge
of a 4-edged rectangular area (e.g. the left edge, as displayed in the
above image). However, the overall rotation angle detection uses
results of up to all four edges. Which edges to use can be specified
by `--deskew-scan-direction`. The final rotation angle will then be
the average value of all rotation angles detected at each
edge. Usually, the individually detected values can be expected to be
almost the same at each edge, if the rectangular area to be deskewed
has a regular shape. If, however, the individual values differ too
much, it can be concluded that something went wrong with the
detection, and no *deskewing* should be performed. (E.g., if the
rotation at the left edge appears to be -0.5 degrees, but at the right
edge results in 1.9 degrees, one should better not use the average
value, because with that big difference something seems to have gone
wrong with the detection.) So, before using the average of all
individually detected values, their statistical standard-deviation is
calculated, which is √((a-average)² + (b-average)² + ...).
If the standard-deviation among the detected angles exceeds the value
specified by `--deskew-scan-deviation`, the total result is considered
to be wrong and no *deskewing* is performed.
*Deskewing* can be disabled with `--no-deskew`, optionally followed by
the *sheet* numbers to disable it for.
## Processing Order
Processing of the filters and auto-corrections is performed in a fixed
order according to the following sequence:
1. **load** image file(s)
2. perform **pre-rotate**, **pre-mirror** etc. actions on the
individual input files (if specified)
3. **place** on the sheet (multiple input-files are placed as tiles),
auto-determine sheet size by the size of the input image-file(s)
if not specified explicitly
4. apply **noisefilter** and **blurfilter** to remove small bits of
unwanted pixels
5. apply **blackfilter** and **grayfilter** to remove larger areas of
unwanted pixels
6. detect **masks** starting from specified mask-scan-points
7. perform **deskewing** on each detected or directly specified
mask
8. **re-detect masks** again to get precise masks after deskewing
9. **center masks** on the corresponding page's area on the sheet
10. perform **border-detection**
11. **align** the detected borders
12. **save** output image file(s), possibly perform **post-rotate**,
**post-mirror** etc. actions on the individual output files before
saving

## Disabling Processing Steps
Each processing step can be disabled individually by a corresponding
`--no-xxx` option (where `xxx` stands for the feature to disable,
e.g. `--no-grayfilter`, `--no-mask-scan` etc.). If such an option is
followed by a *sheet* number, or a comma-separated list of multiple
*sheet* numbers, the filter gets disabled only for those *sheets*
specified. Otherwise (if no *sheet* number follows), the filter is
disabled for all *sheets*. Instead of specifying individual *sheet*
numbers, also a range of numbers can be given, e.g. "10-20" to
represent all *sheet* numbers between 10 and 20. Example:
unpaper (...options...) --no-blackfilter 3,15,21-28,40 (...)
This will disable the *blackfilter* on the *sheets* 3, 15, 21, 22, 23,
etc. until 28, and 40.
|