Line Detection using Multiple Object Tracking
Include
<scribo/segdet.hpp>
-
std::tuple<mln::image2d<std::uint16_t>, std::vector<LSuperposition>> detect_line_pixel(const mln::image2d<std::uint8_t> &input, int min_len, const SegDetParams ¶ms);
-
std::vector<VSegment> detect_line_vector(const mln::image2d<std::uint8_t> &input, int min_len, const SegDetParams ¶ms);
-
std::tuple<mln::image2d<std::uint16_t>, std::vector<LSuperposition>, std::vector<VSegment>> detect_line_full(const mln::image2d<std::uint8_t> &input, int min_len, const SegDetParams ¶ms);
Compute a line detection with a complete pipeline using MOT in a greyscale image.
- Parameters:
input – The input greyscale image
min_len – The minimum length (in pixels) of segments that have to be detected
params – The Parameters struct giving the parameters of the method.
Input
-
enum class scribo::e_segdet_preprocess
e_segdet_preprocess Precise the preprocess to apply
Values:
-
enumerator NONE
None.
-
enumerator BLACK_TOP_HAT
Black-Top-Hat with specific filter size and dynamic.
-
enumerator NONE
-
enum class scribo::e_segdet_process_tracking
e_segdet_process_tracking Precise which tracker is used
Values:
-
enumerator KALMAN
Kalman Filters following classics prediction and correction based on IRISA article.
-
enumerator ONE_EURO
One Euro Filter (modification from Nicolas Roussel code)
-
enumerator DOUBLE_EXPONENTIAL
Double exponential.
-
enumerator LAST_INTEGRATION
Last observation.
-
enumerator SIMPLE_MOVING_AVERAGE
Simple moving average.
-
enumerator EXPONENTIAL_MOVING_AVERAGE
Exponential moving average.
-
enumerator KALMAN
-
enum class scribo::e_segdet_process_extraction
Values:
-
enumerator BINARY
Binary extraction with threshold.
-
enumerator GRADIENT
Gradient extraction with threshold.
-
enumerator BINARY
-
enum class scribo::e_segdet_process_traversal_mode
e_segdet_process_traversal_mode Precise the traversal performed for line detection
Values:
-
enumerator HORIZONTAL
Only horizontal traversal is performed.
-
enumerator VERTICAL
Only vertical traversal is performed.
-
enumerator HORIZONTAL_VERTICAL
Both horizontal and vertical traversal are performed.
-
enumerator HORIZONTAL
-
struct SegDetParams
SegDetParams holds parameters of the line detection.
Public Functions
-
bool is_valid() const
Say if parameters values are compatible.
- Returns:
true if parameters are valid
Public Members
-
e_segdet_preprocess preprocess = e_segdet_preprocess::NONE
Preprocess applied.
-
e_segdet_process_tracking tracker = e_segdet_process_tracking::KALMAN
Tracker used.
-
e_segdet_process_traversal_mode traversal_mode = e_segdet_process_traversal_mode::HORIZONTAL_VERTICAL
Traversal performed.
-
e_segdet_process_extraction extraction_type = e_segdet_process_extraction::BINARY
Extraction type for observations.
-
bool negate_image = false
Say if image has to be reversed before processing.
-
float dyn = 0.6f
Dynamic when Black-Top-Hat preprocess is applied.
-
int size_mask = 11
Filter size when Black-Top-Hat preprocess is applied.
-
float double_exponential_alpha = 0.6f
Alpha used in double exponential tracker if chosen.
-
float simple_moving_average_memory = 30.0f
Memory used in simple moving average tracker if chosen.
-
float exponential_moving_average_memory = 16.0f
Memory used in exponential moving average tracker if chosen.
-
float one_euro_beta = 0.007f
Beta used in one euro tracker if chosen.
-
float one_euro_mincutoff = 1.0f
Min cutoff used in one euro tracker if chosen.
-
float one_euro_dcutoff = 1.0f
Dcutoff used in one euro tracker if chosen.
-
int bucket_size = 32
Bucket size during traversal.
-
int nb_values_to_keep = 30
Memory of tracker to compute variances for the matching.
-
int discontinuity_relative = 0
Percentage. Discontinuity = discontinuity_absolute + discontinuity_relative * current_segment_size.
-
int discontinuity_absolute = 0
Discontinuity = discontinuity_absolute + discontinuity_relative * current_segment_size.
-
int minimum_for_fusion = 15
Threshold to merge trackers following same observation.
-
int default_sigma_position = 2
Position default variance value.
-
int default_sigma_thickness = 2
Thickness default variance value.
-
int default_sigma_luminosity = 57
Luminosity default variance value.
-
int min_nb_values_sigma = 10
Threshold to compute variance and not use defauld values.
-
float sigma_pos_min = 1.f
Minimum position variance value.
-
float sigma_thickness_min = 0.64f
Minimum thickness variance value.
-
float sigma_luminosity_min = 13.f
Minimum luminosity variance value.
-
int gradient_threshold = 30
Gradient threshold when gradient preprocess is applied.
-
int llumi = 225
First threshold for observation ternary extraction.
-
int blumi = 225
Second threshold for observation ternary extraction.
-
float ratio_lum = 1.f
Ratio of kept luminosity in observation extraction.
-
int max_thickness = 100
Max allowed (vertical|horizontal) thickness of segment to detect.
-
float threshold_intersection = 0.8f
Threshold for duplication removal.
-
bool remove_duplicates = true
Say if duplication removal has to be computed.
-
bool is_valid() const
Outputs
-
struct LSuperposition
LSuperposition structure holding superposition information.
Definition
Retrieving straight or slightly curved lines out of document images can be a essentiel step of document analysis. This method retrieves such lines by iteratively predicting the position of spans of pixels in the input image columns. In order to do so, it makes use of Kalman filters to integrate the observed measurements and determine what is and what is not a segment.
Usage
Retrieve lines in document images
int min_len = 20;
scribo::SegDetParams params = {.traversal_mode = scribo::e_segdet_process_traversal_mode::HORIZONTAL,
.discontinuity_relative = 30,
.max_thickness = 5};
auto [labelled_image, superposition_vector, vsegment_vector] = scribo::detect_line_full(input, min_len, params);
Build vectorial output image
mln::image2d<argb8> out_vector(input.width(), input.height(),
mln::image_build_params{.border = 0, .init_value = {}});
mln::transform(input, out_vector, [](int x) { return x != 0 ? argb8{255, 255, 255, 255} : argb8{0, 0, 0, 255}; });
render_image_vector(out_vector, vsegment_vector, output_filepath_vector);
Build pixel output image
mln_foreach (auto pt, labelled_image.domain())
labelled_image(pt) = labelled_image(pt) == 0 ? (input(pt) != 0 ? 1 : 0) : labelled_image(pt);
mln::io::imsave(mln::view::transform(labelled_image, [](auto x) { return regions_lut(x); }), output_filepath_pixel);
Display superposition information
for (auto superposition : superposition_vector)
fmt::print("label={}; x={}; y={}\n", superposition.label, superposition.x, superposition.y);
(Full code: /snippets/segdet.cpp
)
Input image |
Scribo lines detected vector (super-imposed) |
Scribo lines detected pixel (super-imposed) |
References
Leplumey, Ivan, Jean Camillerapp, and Charles Queguiner. “Kalman filter contributions towards document segmentation.” Proceedings of 3rd International Conference on Document Analysis and Recognition. Vol. 2. IEEE, 1995.