treadscan.utilities
Ellipse
- class treadscan.utilities.Ellipse(cx: int, cy: int, width: int, height: int, angle: float)
Class which defines an ellipse.
- Attributes
- cxint
X coordinate of center.
- cyint
Y coordinate of center.
- widthint
Width of ellipse (size across the X axis if angle is 0).
- heightint
Height of ellipse (size across the Y axis if angle is 0).
- anglefloat
Angle in degrees defining the ellipse rotation (clockwise tilt).
Methods
get_center()
Returns center coordinates as tuple.
point_on_ellipse(deg: float)
Returns point on ellipse perimeter.
is_point_inside(point: (int, int))
Checks whether point lies inside or outside the ellipse.
distance_between_point(point: (int, int))
Calculates the shortest distance between ellipse and point.
horizontal_distance_between_point(point: (int, int))
Calculates the length of a line drawn horizontally (relative to major axis) from the ellipse to the point.
cv2_ellipse(start: float, end: float)
Returns self as list, which when unpacked (star operator) is compatible with cv2.ellipse() drawing operation.
horizontal_distance_between_point(x: int, y: int)
Returns the length of a horizontal line drawn from point and intersecting with the ellipse. Only implemented for non-rotated ellipse.
fit_to_intersect(point: (int, int))
Scales ellipse to intersect given point.
bounding_box():
Returns top left and bottom right points of ellipse’s bounding box.
area():
Returns ellipse’s area.
- area() float
Calculate area of ellipse.
- Returns
- float
Area of ellipse.
- bounding_box() list
Create bounding box around ellipse. Compatible with OpenCV’s cv2.rectangle() drawing operation (returns points as integer tuples).
- Returns
- list
List of two points (tuples) - top left and bottom right corner of bounding box.
- cv2_ellipse(start: float = 0, end: float = 360) list
Returns self as list, which when unpacked (star operator) is compatible with cv2.ellipse() drawing operation. For example as cv2.ellipse(my_image, *my_ellipse.cv2_ellipse(), color=(255, 64, 255), thickness=5).
- Returns
- list
List of (center coordinates), (axes), angle, start angle, end angle.
- distance_between_point(point: (<class 'int'>, <class 'int'>)) float
Calculate distance between point and ellipse.
- Parameters
- point(int, int)
X and Y coordinates.
- Returns
- float
Distance between point and ellipse.
- fit_to_intersect(point: (<class 'int'>, <class 'int'>))
Extend ellipse to intersect given point.
- Parameters
- point(int, int)
X and Y coordinates.
- get_center() -> (<class 'int'>, <class 'int'>)
Returns center coordinates as tuple.
- Returns
- (int, int)
X and Y coordinates.
- horizontal_distance_between_point(point: (<class 'int'>, <class 'int'>)) int
Approximate angle which gives the closest point on the right side of ellipse to provided point if you were to draw a horizontal line.
- Parameters
- point(int, int)
X and Y coordinates.
- Returns
- int
Length of horizontal (relative to ellipse) line drawn from (x, y) and intersecting ellipse.
- is_point_inside(point: (<class 'int'>, <class 'int'>)) bool
Check if point is inside or outside of ellipse.
- Parameters
- point: (int, int)
X and Y coordinates.
- Returns
- bool
True if inside or on ellipse, False if outside.
- point_on_ellipse(deg: float) -> (<class 'float'>, <class 'float'>)
Calculate point on ellipse perimeter, accounting for center offset.
- Parameters
- degfloat
Angle on ellipse.
0 and 180 lie on X axis (same X as center).
90 and 270 lie on Y axis (same Y as center).
- Returns
- (float, float)
X and Y coordinates of point on ellipse perimeter. X and Y coordinates in image (where ellipse is). Origin is in top left corner, NOT the ellipse center.
ellipse_from_points()
- treadscan.utilities.ellipse_from_points(top: (<class 'int'>, <class 'int'>), bottom: (<class 'int'>, <class 'int'>), third: (<class 'int'>, <class 'int'>)) Ellipse
Create ellipse from 3 points. Top and bottom are ellipse vertices, third point lies anywhere on the ellipse.
- Parameters
- top(int, int)
X and Y coordinates of the top of the ellipse (at -90 degrees).
- bottom(int, int)
X and Y coordinates of the bottom of the ellipse (at 90 degrees).
- third(int, int)
X and Y coordinates of any point on the ellipse (except top or bottom).
- Returns
- treadscan.Ellipse
Ellipse constructed from the provided points.
euclidean_dist()
- treadscan.utilities.euclidean_dist(a: Union[tuple, list], b: Union[tuple, list]) float
Return the Euclidean distance between two points
- Parameters
- a: Union[(int, int), [int, int]]
- b: Union[(int, int), [int, int]]
- Returns
- float
Euclidean distance between points
rotate_point()
- treadscan.utilities.rotate_point(point: (<class 'int'>, <class 'int'>), angle: float, pivot: (<class 'int'>, <class 'int'>) = (0, 0)) -> (<class 'int'>, <class 'int'>)
Return point rotated by angle around given origin.
- Parameters
- point(int, int)
Original point coordinates.
- anglefloat
Angle in degrees to rotate point by.
- pivot: (int, int)
Center of rotation, (0, 0) by default.
- Returns
- (int, int)
New coordinates of point.
Notes
Source: https://stackoverflow.com/a/15109215.
load_image()
- treadscan.utilities.load_image(path: str)
Load grayscale image from given path.
- Parameters
- pathstr
Path to image.
- Returns
- numpy.ndarray
Grayscale image as 2D array.
- Raises
- ValueError
When file does not exist or is not readable.
scale_image()
- treadscan.utilities.scale_image(image: ndarray, factor: float, interpolation_method: Optional[int] = None) ndarray
Scale image by factor. Returns new instance of rescaled image.
- Parameters
- imagenumpy.ndarray
Image to scale by factor.
- factorfloat
Multiplies width and height (resolution) of image.
- interpolation_methodint
OpenCV interpolation method. If None, uses cv2.INTER_AREA when shrinking (factor < 1) and cv2.INTER_LINEAR when up-scaling (factor > 1). For more info about interpolation methods see OpenCV documentation (https://docs.opencv.org/3.4/da/d54/group__imgproc__transform.html).
cv2.INTER_NEAREST : Nearest neighbor interpolation.
cv2.INTER_LINEAR : Bilinear interpolation.
cv2.INTER_CUBIC : Bicubic interpolation.
cv2.INTER_AREA : Pixel area relation.
cv2.INTER_LANCZOS4 : Lanczos interpolation over 8x8 neighborhood.
- Returns
- numpy.ndarray
Scaled image.
subsample_hash()
- treadscan.utilities.subsample_hash(array: ndarray, sample_size: int = 1024, seed: int = 666) int
Hash of NumPy array using array samples. It is best to always use the same sample_size and seed, to avoid the possibility of the same array having different hashes.
- Parameters
- arraynumpy.ndarray
NumPy array for which to compute hash.
- sample_sizeint
Number of samples to take. Higher number means more entropy, but slower computation. Using different sample sizes over the same array will most likely produce different hashes.
- seedint
Seed used to randomly choose samples. Using different seeds over the same array will most likely produce different hashes.
- Returns
- int
Hash of taken samples.
Notes
Idea taken from https://stackoverflow.com/a/23300771.
image_histogram()
- treadscan.utilities.image_histogram(image: ndarray) ndarray
Calculate normalized histogram of grayscale image.
- Parameters
- imagenumpy.ndarray
Input image (grayscale, 2D array).
- Returns
- numpy.ndarray
Normalized histogram (sum equals 1).
- Raises
- ValueError
When input image isn’t grayscale.
perspective_transform_y_axis()
- treadscan.utilities.perspective_transform_y_axis(angle: float, point: (<class 'int'>, <class 'int'>), image_size: (<class 'int'>, <class 'int'>)) -> (<class 'int'>, <class 'int'>)
Perspective rotation around Y axis (center of image), takes original X and Y coordinates, returns transformed.
- Parameters
- anglefloat
Angle of rotation in degrees (rotation around Y axis).
- point(int, int)
X and Y coordinates.
- image_size(int, int)
Height and width of image.
- Returns
- (int, int)
Tuple of transformed X and Y coordinates (position after perspective transformation).
Notes
\(A1\) is a projection matrix from 2D to 3D, \(RY\) is a rotation matrix (around the Y axis), \(T\) is the translation matrix and \(A2\) is a projection matrix back from 3D to 2D. [1]
\[ \begin{align}\begin{aligned}\begin{split}A1 = \begin{pmatrix} 1 & 0 & -\frac{w}{2} \\ 0 & 1 & -\frac{h}{2} \\ 0 & 0 & 1 \\ 0 & 0 & 1 \end{pmatrix}\end{split}\\\begin{split}RY = \begin{pmatrix} \cos(\varphi) & 0 & -\sin(\varphi) & 0 \\ 0 & 1 & 0 & 0 \\ \sin(\varphi) & 0 & \cos(\varphi) & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}\end{split}\\\begin{split}T = \begin{pmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & f \\ 0 & 0 & 1 \end{pmatrix}\end{split}\\\begin{split}A2 = \begin{pmatrix} f & 0 & \frac{w}{2} & 0 \\ 0 & f & \frac{h}{2} & 0 \\ 0 & 0 & 1 & 0 \end{pmatrix}\end{split}\end{aligned}\end{align} \]\(f\) is calculated as \(\sqrt{\texttt{width}^2 + \texttt{height}^2}\).
\(\varphi\) is the angle of rotation around the Y axis.
The final transformation matrix is then given by
\[M = \Big( A2 \cdot \big( T \cdot ( R \cdot A1 ) \big) \Big).\]And the transformation of the points \(x\) and \(y\) is [2]
\[\texttt{dst}(x, y) = \left( \frac{M_{11}x + M_{12}y + M_{13}}{M_{31}x + M_{32}y + M_{33}}, \frac{M_{21}x + M_{22}y + M_{23}}{M_{31}x + M_{32}y + M_{33}} \right).\]- 1
M. Jepson, https://jepsonsblog.blogspot.com/2012/11/rotation-in-3d-using-opencvs.html 28 November 2012
- 2
OpenCV documentation, https://docs.opencv.org/4.x/da/d54/group__imgproc__transform.html#gaf73673a7e8e18ec6963e3774e6a94b87 3 February 2022
remove_gradient()
- treadscan.utilities.remove_gradient(image: ~numpy.ndarray, blur_kernel_size: (<class 'int'>, <class 'int'>) = (0, 0)) ndarray
Attempts to remove effects of (vertical) gradient lighting in image.
- Parameters
- imagenumpy.ndarray
Original (grayscale) image.
- blur_kernel_size(int, int)
Optional parameter to change shape of kernel (width, height) used to find gradient. (Horizontal kernels will find vertical gradient and vice-versa.) By default, this method removes vertical gradient.
- Returns
- numpy.ndarray
Image without gradient.
- Raises
- ValueError
If image is not grayscale or has invalid resolution.
clahe()
- treadscan.utilities.clahe(image: ndarray, clip_limit: float = 8.0, tile_grid_size: Union[int, tuple] = 4) ndarray
Contrast limited adaptive histogram equalization (CLAHE).
- Parameters
- image: numpy.ndarray
Grayscale image.
- clip_limit: float
Threshold for contrast limiting.
- tile_grid_size: Union[int, tuple]
Size of grid for histogram equalization.