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.