Source code for ovl.math.shape_fill_ratios
import typing
import cv2
import numpy as np
from .geometry import circle_area
[docs]def rectangle_fill_ratio_straight(contour, reverse_div=False):
"""
Returns the ratio between the contour and the straight bounding rectangle.
:param contour: The contour to be compared
:param reverse_div: If the rectangle's area should be divided by the contour.
:return: the ratio, the width of the bounding rectangle, the height of the bounding rectangle
:rtype: float
"""
_, _, width, height = cv2.boundingRect(contour)
bounding_rectangle_area = width * height
contour_area = cv2.contourArea(contour)
if reverse_div:
return float(bounding_rectangle_area) / contour_area, width, height
return float(contour_area) / bounding_rectangle_area, width, height
[docs]def triangle_fill_ratio(contour, triangle=None) -> float:
"""
Returns the ratio between a given contour and the smallest enclosing rectangle
:param contour: numpy array
:param triangle: convex hull for the minEnclosingTriangle function, can be ignored
:return: returns the ratio between the contour and the bounding triangle
:rtype: float
"""
bounding_triangle_area, triangle = cv2.minEnclosingTriangle(contour, triangle)
contour_area = cv2.contourArea(contour)
return contour_area / float(bounding_triangle_area)
[docs]def rotating_rectangle_fill_ratio(contour: np.ndarray) -> typing.Tuple[float, float, float]:
"""
Returns the ratio between the contour and the smallest bounding rectangle.
:param contour: The contour to be compared
:return: the ratio, the width of the bounding rectangle, the height of the bounding rectangle
:rtype: float, float, float
"""
rotated = cv2.minAreaRect(contour)
bounding_rectangle_area = rotated[1][0] * rotated[1][1]
contour_area = cv2.contourArea(contour)
return float(contour_area) / bounding_rectangle_area, rotated[1][0], rotated[1][1]
[docs]def circle_fill_ratio(contour: np.ndarray) -> typing.Tuple[float, float]:
"""
Returns the ratio between the contour and the smallest enclosing circle.
:param contour: The contour to be compared
:return: the ratio, the radius of the enclosing circle
:rtype: float
"""
_, enclosing_radius = cv2.minEnclosingCircle(contour)
enclosing_circle_area = circle_area(enclosing_radius)
contour_area = cv2.contourArea(contour)
return float(contour_area) / enclosing_circle_area, enclosing_radius