0
# Geometric Operations
1
2
Rectangle manipulation, line operations, transformations, and geometric utilities for computer vision applications and spatial computations.
3
4
## Capabilities
5
6
### Rectangle Operations
7
8
Rectangle classes for representing and manipulating rectangular regions with comprehensive geometric operations.
9
10
```python { .api }
11
class rectangle:
12
"""Rectangular area with integer coordinates."""
13
14
def __init__(self, left: int, top: int, right: int, bottom: int):
15
"""Create rectangle from coordinates."""
16
17
def __init__(self, drectangle_obj: drectangle):
18
"""Create from floating point rectangle."""
19
20
def __init__(self):
21
"""Create empty rectangle."""
22
23
def left(self) -> int:
24
"""Get left coordinate."""
25
26
def top(self) -> int:
27
"""Get top coordinate."""
28
29
def right(self) -> int:
30
"""Get right coordinate."""
31
32
def bottom(self) -> int:
33
"""Get bottom coordinate."""
34
35
def width(self) -> int:
36
"""Get rectangle width."""
37
38
def height(self) -> int:
39
"""Get rectangle height."""
40
41
def area(self) -> int:
42
"""Get rectangle area."""
43
44
def tl_corner(self) -> point:
45
"""Get top-left corner point."""
46
47
def tr_corner(self) -> point:
48
"""Get top-right corner point."""
49
50
def bl_corner(self) -> point:
51
"""Get bottom-left corner point."""
52
53
def br_corner(self) -> point:
54
"""Get bottom-right corner point."""
55
56
def is_empty(self) -> bool:
57
"""Check if rectangle is empty."""
58
59
def center(self) -> point:
60
"""Get center point as integer coordinates."""
61
62
def dcenter(self) -> dpoint:
63
"""Get center point as float coordinates."""
64
65
def contains(self, point_obj) -> bool:
66
"""Check if point is inside rectangle."""
67
68
def contains(self, rect: rectangle) -> bool:
69
"""Check if rectangle is inside this rectangle."""
70
71
def intersect(self, rect: rectangle) -> rectangle:
72
"""Get intersection with another rectangle."""
73
74
class drectangle:
75
"""Rectangular area with floating point coordinates."""
76
77
def __init__(self, left: float, top: float, right: float, bottom: float):
78
"""Create rectangle from coordinates."""
79
80
def __init__(self, rectangle_obj: rectangle):
81
"""Create from integer rectangle."""
82
83
def __init__(self):
84
"""Create empty rectangle."""
85
86
def left(self) -> float:
87
"""Get left coordinate."""
88
89
def top(self) -> float:
90
"""Get top coordinate."""
91
92
def right(self) -> float:
93
"""Get right coordinate."""
94
95
def bottom(self) -> float:
96
"""Get bottom coordinate."""
97
98
def width(self) -> float:
99
"""Get rectangle width."""
100
101
def height(self) -> float:
102
"""Get rectangle height."""
103
104
def area(self) -> float:
105
"""Get rectangle area."""
106
107
def tl_corner(self) -> dpoint:
108
"""Get top-left corner point."""
109
110
def tr_corner(self) -> dpoint:
111
"""Get top-right corner point."""
112
113
def bl_corner(self) -> dpoint:
114
"""Get bottom-left corner point."""
115
116
def br_corner(self) -> dpoint:
117
"""Get bottom-right corner point."""
118
119
def is_empty(self) -> bool:
120
"""Check if rectangle is empty."""
121
122
def center(self) -> point:
123
"""Get center point as integer coordinates."""
124
125
def dcenter(self) -> dpoint:
126
"""Get center point as float coordinates."""
127
128
def contains(self, point_obj) -> bool:
129
"""Check if point is inside rectangle."""
130
131
def contains(self, rect: drectangle) -> bool:
132
"""Check if rectangle is inside this rectangle."""
133
134
def intersect(self, rect: drectangle) -> drectangle:
135
"""Get intersection with another rectangle."""
136
```
137
138
**Usage Example:**
139
```python
140
import dlib
141
142
# Create rectangles
143
rect1 = dlib.rectangle(10, 20, 100, 80)
144
rect2 = dlib.drectangle(15.5, 25.5, 95.5, 75.5)
145
146
# Basic properties
147
print(f"Area: {rect1.area()}") # 5400
148
print(f"Width: {rect1.width()}, Height: {rect1.height()}") # 90, 60
149
print(f"Center: {rect1.dcenter()}") # (55.0, 50.0)
150
151
# Corner points
152
tl = rect1.tl_corner() # Top-left: (10, 20)
153
br = rect1.br_corner() # Bottom-right: (100, 80)
154
155
# Containment tests
156
point_inside = dlib.point(50, 50)
157
print(rect1.contains(point_inside)) # True
158
159
# Intersection
160
intersection = rect1.intersect(dlib.rectangle(50, 50, 150, 100))
161
```
162
163
### Rectangle Container Types
164
165
Container classes for managing collections of rectangles.
166
167
```python { .api }
168
class rectangles:
169
"""Array of rectangle objects."""
170
171
def clear(self):
172
"""Remove all rectangles."""
173
174
def resize(self, size: int):
175
"""Resize container."""
176
177
def extend(self, rect_list: list):
178
"""Add rectangles from list."""
179
180
class rectangless:
181
"""Array of arrays of rectangle objects."""
182
183
def clear(self):
184
"""Remove all rectangle arrays."""
185
186
def resize(self, size: int):
187
"""Resize container."""
188
189
def extend(self, rectangles_list: list):
190
"""Add rectangle arrays from list."""
191
```
192
193
### Rectangle Manipulation Functions
194
195
Utility functions for creating and manipulating rectangles.
196
197
```python { .api }
198
def translate_rect(rect: rectangle, offset: point) -> rectangle:
199
"""
200
Move rectangle by offset.
201
202
Args:
203
rect: Rectangle to translate
204
offset: Translation offset
205
206
Returns:
207
Translated rectangle
208
"""
209
210
def shrink_rect(rect: rectangle, amount: int) -> rectangle:
211
"""
212
Shrink rectangle border by amount.
213
214
Args:
215
rect: Rectangle to shrink
216
amount: Amount to shrink each side
217
218
Returns:
219
Shrunk rectangle
220
"""
221
222
def grow_rect(rect: rectangle, amount: int) -> rectangle:
223
"""
224
Expand rectangle border by amount.
225
226
Args:
227
rect: Rectangle to expand
228
amount: Amount to expand each side
229
230
Returns:
231
Expanded rectangle
232
"""
233
234
def scale_rect(rect: rectangle, scale: float) -> rectangle:
235
"""
236
Scale rectangle by factor.
237
238
Args:
239
rect: Rectangle to scale
240
scale: Scale factor
241
242
Returns:
243
Scaled rectangle
244
"""
245
246
def centered_rect(center: point, width: int, height: int) -> rectangle:
247
"""
248
Create rectangle centered at point.
249
250
Args:
251
center: Center point
252
width: Rectangle width
253
height: Rectangle height
254
255
Returns:
256
Centered rectangle
257
"""
258
259
def centered_rect(rect: rectangle, width: int, height: int) -> rectangle:
260
"""
261
Create rectangle centered at rectangle center.
262
263
Args:
264
rect: Reference rectangle for center
265
width: New rectangle width
266
height: New rectangle height
267
268
Returns:
269
Centered rectangle
270
"""
271
272
def centered_rects(centers: points, width: int, height: int) -> rectangles:
273
"""
274
Create multiple centered rectangles.
275
276
Args:
277
centers: Center points
278
width: Rectangle width
279
height: Rectangle height
280
281
Returns:
282
Array of centered rectangles
283
"""
284
285
def center(rect: rectangle) -> point:
286
"""
287
Get rectangle center point.
288
289
Args:
290
rect: Rectangle
291
292
Returns:
293
Center point
294
"""
295
```
296
297
**Usage Example:**
298
```python
299
import dlib
300
301
# Create base rectangle
302
rect = dlib.rectangle(10, 10, 90, 60)
303
304
# Manipulate rectangles
305
moved_rect = dlib.translate_rect(rect, dlib.point(20, 30))
306
bigger_rect = dlib.grow_rect(rect, 10)
307
smaller_rect = dlib.shrink_rect(rect, 5)
308
309
# Create centered rectangles
310
center_point = dlib.point(100, 100)
311
centered = dlib.centered_rect(center_point, 50, 30)
312
313
# Multiple centered rectangles
314
centers = dlib.points()
315
centers.extend([dlib.point(50, 50), dlib.point(150, 100)])
316
rects = dlib.centered_rects(centers, 40, 40)
317
```
318
319
### Rectangle Filtering
320
321
Kalman filter for tracking rectangles over time with configurable noise parameters.
322
323
```python { .api }
324
class rect_filter:
325
"""Kalman filter for tracking rectangles."""
326
327
def __init__(self, measurement_noise: float, typical_acceleration: float, max_measurement_deviation: float):
328
"""
329
Initialize rectangle filter.
330
331
Args:
332
measurement_noise: Expected measurement noise level
333
typical_acceleration: Expected acceleration magnitude
334
max_measurement_deviation: Maximum allowed measurement deviation
335
"""
336
337
def measurement_noise(self) -> float:
338
"""Get measurement noise parameter."""
339
340
def typical_acceleration(self) -> float:
341
"""Get typical acceleration parameter."""
342
343
def max_measurement_deviation(self) -> float:
344
"""Get max measurement deviation parameter."""
345
346
def __call__(self, rect: rectangle) -> rectangle:
347
"""
348
Filter rectangle measurement.
349
350
Args:
351
rect: Measured rectangle
352
353
Returns:
354
Filtered rectangle
355
"""
356
357
def find_optimal_rect_filter(rects: rectangles, smoothness: float = 1.0) -> rect_filter:
358
"""
359
Find optimal rectangle filter parameters.
360
361
Args:
362
rects: Sequence of rectangle measurements
363
smoothness: Smoothness parameter (higher = smoother)
364
365
Returns:
366
Optimally configured rectangle filter
367
"""
368
```
369
370
**Usage Example:**
371
```python
372
import dlib
373
374
# Create filter for rectangle tracking
375
rect_filter = dlib.rect_filter(
376
measurement_noise=10.0,
377
typical_acceleration=0.1,
378
max_measurement_deviation=3.0
379
)
380
381
# Track rectangles over time
382
measurements = [
383
dlib.rectangle(100, 100, 150, 140),
384
dlib.rectangle(102, 103, 152, 143),
385
dlib.rectangle(105, 106, 155, 146)
386
]
387
388
filtered_rects = []
389
for rect in measurements:
390
filtered = rect_filter(rect)
391
filtered_rects.append(filtered)
392
393
# Or find optimal parameters automatically
394
optimal_filter = dlib.find_optimal_rect_filter(measurements, smoothness=2.0)
395
```
396
397
### Line Operations
398
399
2D line representation and geometric operations for line-based computations.
400
401
```python { .api }
402
class line:
403
"""2D line representation."""
404
405
def __init__(self):
406
"""Create empty line."""
407
408
def __init__(self, p1: point, p2: point):
409
"""Create line from two points."""
410
411
p1: point # First endpoint
412
p2: point # Second endpoint
413
414
@property
415
def normal(self) -> dpoint:
416
"""Unit normal vector to the line."""
417
418
def signed_distance_to_line(line_obj: line, point_obj: point) -> float:
419
"""
420
Compute signed distance from point to line.
421
422
Args:
423
line_obj: Line
424
point_obj: Point
425
426
Returns:
427
Signed distance (positive on one side, negative on other)
428
"""
429
430
def distance_to_line(line_obj: line, point_obj: point) -> float:
431
"""
432
Compute absolute distance from point to line.
433
434
Args:
435
line_obj: Line
436
point_obj: Point
437
438
Returns:
439
Absolute distance
440
"""
441
442
def reverse(line_obj: line) -> line:
443
"""
444
Reverse line direction.
445
446
Args:
447
line_obj: Input line
448
449
Returns:
450
Line with reversed direction
451
"""
452
453
def intersect(line_a: line, line_b: line) -> point:
454
"""
455
Find intersection point of two lines.
456
457
Args:
458
line_a: First line
459
line_b: Second line
460
461
Returns:
462
Intersection point
463
"""
464
465
def angle_between_lines(line_a: line, line_b: line) -> float:
466
"""
467
Compute angle between lines in degrees.
468
469
Args:
470
line_a: First line
471
line_b: Second line
472
473
Returns:
474
Angle in degrees
475
"""
476
477
def count_points_on_side_of_line(
478
line_obj: line,
479
reference_point: point,
480
points_list: points,
481
dist_thresh_min: float = 0.0,
482
dist_thresh_max: float = float('inf')
483
) -> int:
484
"""
485
Count points on same side of line as reference point.
486
487
Args:
488
line_obj: Reference line
489
reference_point: Reference point to determine side
490
points_list: Points to test
491
dist_thresh_min: Minimum distance threshold
492
dist_thresh_max: Maximum distance threshold
493
494
Returns:
495
Number of points on same side within distance thresholds
496
"""
497
498
def count_points_between_lines(
499
line1: line,
500
line2: line,
501
reference_point: point,
502
points_list: points
503
) -> int:
504
"""
505
Count points between two lines.
506
507
Args:
508
line1: First line
509
line2: Second line
510
reference_point: Reference point
511
points_list: Points to test
512
513
Returns:
514
Number of points between the lines
515
"""
516
```
517
518
**Usage Example:**
519
```python
520
import dlib
521
522
# Create lines
523
p1, p2 = dlib.point(0, 0), dlib.point(100, 100)
524
p3, p4 = dlib.point(0, 100), dlib.point(100, 0)
525
526
line1 = dlib.line(p1, p2)
527
line2 = dlib.line(p3, p4)
528
529
# Line operations
530
intersection = dlib.intersect(line1, line2) # Should be (50, 50)
531
angle = dlib.angle_between_lines(line1, line2) # 90 degrees
532
533
# Distance calculations
534
test_point = dlib.point(25, 75)
535
distance = dlib.distance_to_line(line1, test_point)
536
signed_dist = dlib.signed_distance_to_line(line1, test_point)
537
538
# Point counting
539
points_list = dlib.points()
540
points_list.extend([dlib.point(10, 10), dlib.point(90, 90), dlib.point(10, 90)])
541
ref_point = dlib.point(0, 50)
542
543
count = dlib.count_points_on_side_of_line(line1, ref_point, points_list)
544
```
545
546
### Projective Transformations
547
548
Projective transformation estimation and application for perspective correction and geometric rectification.
549
550
```python { .api }
551
class point_transform_projective:
552
"""Projective transformation for point mapping."""
553
554
def __init__(self):
555
"""Create identity transformation."""
556
557
def __call__(self, point_obj: point) -> dpoint:
558
"""
559
Apply transformation to point.
560
561
Args:
562
point_obj: Input point
563
564
Returns:
565
Transformed point
566
"""
567
568
def find_projective_transform(from_points: points, to_points: points) -> point_transform_projective:
569
"""
570
Find projective transformation from point correspondences.
571
572
Args:
573
from_points: Source points (at least 4 points)
574
to_points: Destination points (same number as from_points)
575
576
Returns:
577
Projective transformation object
578
"""
579
580
def inv(transform: point_transform_projective) -> point_transform_projective:
581
"""
582
Compute inverse of projective transformation.
583
584
Args:
585
transform: Input transformation
586
587
Returns:
588
Inverse transformation
589
"""
590
```
591
592
### Vector Operations
593
594
Mathematical operations on points and vectors for geometric computations.
595
596
```python { .api }
597
def dot(vector1, vector2) -> float:
598
"""
599
Compute dot product of two vectors/points.
600
601
Args:
602
vector1: First vector (point or dpoint)
603
vector2: Second vector (point or dpoint)
604
605
Returns:
606
Dot product
607
"""
608
609
def length(point_obj) -> float:
610
"""
611
Compute vector length/magnitude.
612
613
Args:
614
point_obj: Point or vector
615
616
Returns:
617
Length of vector
618
"""
619
620
def polygon_area(points_list: points) -> float:
621
"""
622
Calculate area of polygon defined by points.
623
624
Args:
625
points_list: Polygon vertices in order
626
627
Returns:
628
Polygon area (positive for counter-clockwise, negative for clockwise)
629
"""
630
```
631
632
**Usage Examples:**
633
634
### Perspective Correction
635
```python
636
import dlib
637
import cv2
638
639
# Load image with perspective distortion
640
img = cv2.imread("document.jpg")
641
642
# Define source corners (distorted quadrilateral)
643
src_corners = dlib.points()
644
src_corners.extend([
645
dlib.point(120, 150), # Top-left
646
dlib.point(380, 100), # Top-right
647
dlib.point(400, 350), # Bottom-right
648
dlib.point(100, 400) # Bottom-left
649
])
650
651
# Define target corners (rectangular)
652
dst_corners = dlib.points()
653
dst_corners.extend([
654
dlib.point(0, 0), # Top-left
655
dlib.point(300, 0), # Top-right
656
dlib.point(300, 400), # Bottom-right
657
dlib.point(0, 400) # Bottom-left
658
])
659
660
# Find projective transformation
661
transform = dlib.find_projective_transform(src_corners, dst_corners)
662
663
# Apply transformation to image using extract_image_4points
664
corners_list = [src_corners[i] for i in range(4)]
665
corrected = dlib.extract_image_4points(img, corners_list, 400, 300)
666
667
# Display results
668
win = dlib.image_window(corrected, "Perspective Corrected")
669
win.wait_until_closed()
670
```
671
672
### Geometric Analysis
673
```python
674
import dlib
675
676
# Create polygon points
677
polygon = dlib.points()
678
polygon.extend([
679
dlib.point(0, 0),
680
dlib.point(100, 0),
681
dlib.point(100, 100),
682
dlib.point(0, 100)
683
])
684
685
# Calculate polygon area
686
area = dlib.polygon_area(polygon)
687
print(f"Polygon area: {area}") # 10000 (100x100 square)
688
689
# Vector operations
690
v1 = dlib.point(3, 4)
691
v2 = dlib.point(1, 2)
692
693
dot_product = dlib.dot(v1, v2) # 3*1 + 4*2 = 11
694
vector_length = dlib.length(v1) # sqrt(3^2 + 4^2) = 5.0
695
696
print(f"Dot product: {dot_product}")
697
print(f"Vector length: {vector_length}")
698
```
699
700
### Transformation Chain
701
```python
702
import dlib
703
704
# Define transformation points
705
src_points = dlib.points()
706
src_points.extend([
707
dlib.point(0, 0),
708
dlib.point(100, 0),
709
dlib.point(100, 100),
710
dlib.point(0, 100)
711
])
712
713
dst_points = dlib.points()
714
dst_points.extend([
715
dlib.point(50, 25),
716
dlib.point(150, 50),
717
dlib.point(125, 150),
718
dlib.point(25, 125)
719
])
720
721
# Create transformation
722
transform = dlib.find_projective_transform(src_points, dst_points)
723
724
# Apply to new points
725
test_point = dlib.point(50, 50) # Center of source square
726
transformed = transform(test_point)
727
print(f"Transformed point: {transformed}")
728
729
# Create inverse transformation
730
inverse_transform = dlib.inv(transform)
731
back_transformed = inverse_transform(transformed)
732
print(f"Back-transformed point: {back_transformed}") # Should be close to (50, 50)
733
```
734
735
The geometric operations provide fundamental spatial computation capabilities essential for computer vision, image rectification, spatial analysis, and geometric transformations. These operations form the foundation for many advanced computer vision algorithms and spatial reasoning tasks.