spans¶
Spanning and keypoint logic for page dewarping.
This module handles:
- Determining candidate edges between adjacent contours to form "spans."
- Grouping individual contours into spans.
- Sampling keypoint positions along spans.
- Computing overall orientation from those keypoints (to find x/y directions).
- Visualizing spans and their keypoints.
angle_dist ¶
Compute the signed angular distance between two angles.
The distance is corrected to lie within [-π, π].
Source code in src/page_dewarp/spans.py
generate_candidate_edge ¶
generate_candidate_edge(cinfo_a: ContourInfo, cinfo_b: ContourInfo) -> tuple[float, ContourInfo, ContourInfo] | None
Compute a left-to-right candidate edge between two contours.
We want cinfo_a (left) to come before cinfo_b (right), so cinfo_a’s successor
is cinfo_b and cinfo_b’s predecessor is cinfo_a. Specifically, the right
endpoint of cinfo_b should be to the right of the left endpoint of cinfo_a. If
not, we swap them. Then we compute how far apart they are, how much they overlap,
and how different their orientations are. If these checks pass certain thresholds,
we return (score, cinfo_a, cinfo_b), otherwise None.
Source code in src/page_dewarp/spans.py
assemble_spans ¶
assemble_spans(name: str, small: ndarray, pagemask: ndarray, cinfo_list: list[ContourInfo]) -> list[list[ContourInfo]]
Assemble spans of contours from a list of ContourInfo objects.
A 'span' is a left-to-right chain of contours. We generate candidate edges,
sort them by a "score," and build spans by linking successors/predecessors.
Spans are retained only if their total width exceeds SPAN_MIN_WIDTH.
If DEBUG_LEVEL >= 2, the resulting spans are visualized.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
|
A string identifier used for debug display. |
required |
small
|
|
A downsampled image (for visualization). |
required |
pagemask
|
|
A mask for the page region. |
required |
cinfo_list
|
|
A list of ContourInfo objects to link into spans. |
required |
Returns:
| Type | Description |
|---|---|
|
A list of spans, where each span is a list of ContourInfo objects. |
Source code in src/page_dewarp/spans.py
sample_spans ¶
Extract regularly spaced keypoints from each span.
Within each contour's bounding rectangle, we measure the vertical average of pixels in the contour's mask at certain horizontal steps. We then convert all points to normalized coordinates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shape
|
|
The (height, width) of the downsampled image. |
required |
spans
|
|
A list of spans, where each span is a list of ContourInfo objects. |
required |
Returns:
| Type | Description |
|---|---|
|
A list of arrays, each array containing the sampled points (in normalized coords). |
Source code in src/page_dewarp/spans.py
keypoints_from_samples ¶
keypoints_from_samples(name: str, small: ndarray, pagemask: ndarray, page_outline: ndarray, span_points: list[ndarray]) -> tuple[np.ndarray, np.ndarray, list[np.ndarray]]
Compute page corner keypoints and local x/y directions from span samples.
Performs a PCA on the combined sample points to estimate a horizontal axis (x_dir). The vertical axis (y_dir) is orthogonal to x_dir. Then computes the page's four corners by projecting the page outline onto x_dir and y_dir, and forms a convex hull.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
|
A string identifier for debugging. |
required |
small
|
|
Downsampled image (for optional visualization). |
required |
pagemask
|
|
Mask of the page region (for dimension references). |
required |
page_outline
|
|
The polygon outlining the page boundary (numpy array). |
required |
span_points
|
|
List of arrays of normalized keypoints from each span. |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Source code in src/page_dewarp/spans.py
visualize_spans ¶
visualize_spans(name: str, small: ndarray, pagemask: ndarray, spans: list[list[ContourInfo]]) -> None
Render spans as colored regions for debugging.
Each span is drawn as a set of filled contours. The final image dims outside the page mask.
Source code in src/page_dewarp/spans.py
visualize_span_points ¶
visualize_span_points(name: str, small: ndarray, span_points: list[ndarray], corners: ndarray) -> None
Draw keypoints from the spans and highlight the page corners.
Performs a quick PCA per span to show each span's approximate orientation axis. The final page corners are polylined in white.