Graphics operations#

Draw graphical primitives into an image stored in an array. The functions draw_xxx perform a similar operation to the functions plot_xxx from the Spatial Math Toolbox. However the draw_xxx render the graphical primitive into the image pixel array, whereas the plot_xxx use Matplotlib to render the graphical primitive in a figure window.

Drawing primitives (boxes, circles, text) and colour lookup onto OpenCV images.

draw_box(image: ndarray, l: int | None = None, r: int | None = None, t: int | None = None, b: int | None = None, w: int | None = None, h: int | None = None, lb: tuple[int, int] | list[int] | ndarray | None = None, lt: tuple[int, int] | list[int] | ndarray | None = None, rb: tuple[int, int] | list[int] | ndarray | None = None, rt: tuple[int, int] | list[int] | ndarray | None = None, wh: int | tuple[int, int] | list[int] | ndarray | None = None, centre: tuple[int, int] | list[int] | ndarray | None = None, center: tuple[int, int] | list[int] | ndarray | None = None, lbrt: tuple[int, int, int, int] | list[int] | ndarray | None = None, lrbt: tuple[int, int, int, int] | list[int] | ndarray | None = None, ltrb: tuple[int, int, int, int] | list[int] | ndarray | None = None, lbwh: tuple[int, int, int, int] | list[int] | ndarray | None = None, ax: Any = None, color: Any = None, thickness: int = 1, antialias: bool = False) tuple[tuple[int, int], tuple[int, int]][source]#

Draw a box in an image

Parameters:
  • image (ndarray(H,W), ndarray(H,W,P)) – image to draw into, greyscale or color

  • l (int, optional) – left side coordinate

  • r (int, optional) – right side coordinate

  • t (int, optional) – top side coordinate

  • b (int, optional) – bottom side coordinate

  • w (int, optional) – box width

  • h (int, optional) – box height

  • lb (array_like(2), optional) – left-bottom corner [u,v]

  • lt (array_like(2), optional) – left-top corner [u,v]

  • rb (array_like(2), optional) – right-bottom corner (u,v)

  • rt (array_like(2), optional) – right-top corner (u,v)

  • wh (array_like(2), optional) – width and height

  • centre (array_like(2), optional) – box centre (u,v)

  • lbrt (array_like(4), optional) – left-bottom-right-top [xmin, ymin, xmax, ymax]

  • lrbt (array_like(4), optional) – left-right-bottom-top [xmin, ymin, xmax, ymax]

  • ltrb (array_like(4), optional) – bounding box [xmin, ymin, xmax, ymax]

  • lbwh (array_like(4), optional) – left-bottom-width-height [xmin, ymin, width, height]

  • color (scalar or array_like) – color of line

  • thickness (int, optional) – line thickness, -1 to fill, defaults to 1

  • antialias (bool, optional) – use antialiasing, defaults to False

  • ax – axes to draw into

Type:

Matplotlib axes

Returns:

bottom-left and top-right corners of the box

Return type:

(2-tuple, 2-tuple)

Draws a box into the specified image using OpenCV. The input image is modified.

The box can be specified in many ways, any combination of inputs is allowed so long as the box is fully specified:

  • bounding box [xmin, xmax; ymin, ymax]

  • left-top-right-bottom [xmin, ymin, xmax, ymax]

  • left side

  • right side

  • top side

  • bottom side

  • centre and width+height

  • left-bottom and right-top corners

  • left-bottom corner and width+height

  • right-top corner and width+height

  • left-top corner and width+height

where left-bottom is (xmin, ymin), left-top is (xmax, ymax)

Example:

>>> from machinevisiontoolbox import draw_box, idisp
>>> import numpy as np
>>> img = np.zeros((1000, 1000), dtype='uint8')
>>> draw_box(img, lbrt=[100, 300, 700, 500], thickness=2, color=200) # outline box
>>> draw_box(img, lbwh=[300, 400, 500, 400], thickness=-1, color=250) # filled box
>>> idisp(img)

(Source code, png, hires.png, pdf)

_images/graphics-1.png

Warning

For images y increases downwards so top of the box, has a larger v-coordinate, and is lower in the image.

Note

If image has multiple planes then color should have the same number of elements as the image has planes. If it is a scalar that value is used for each color plane. For a color image color can be a string color name.

Seealso:

plot_box opencv.rectangle

draw_circle(image: ndarray, centre: tuple[float, float] | list[float] | ndarray, radius: int, color: Any, thickness: int = 1, antialias: bool = False, center: tuple[float, float] | list[float] | ndarray | None = None) ndarray[source]#

Draw line in image

Parameters:
  • image (ndarray(H,W), ndarray(H,W,P)) – image to draw into, greyscale or color

  • centre – centre coordinate

  • radius – radius in pixels

  • color (scalar, array_like(3)) – color of circle

  • thickness (int, optional) – width of line in pixels, -1 to fill, defaults to 1

  • antialias (bool, optional) – use antialiasing, defaults to False

Raises:

TypeError – can’t draw color into a greyscale image

Returns:

passed image as modified

Return type:

ndarray(H,W), ndarray(H,W,P)

The centre coordinate can be a tuple, list or NumPy array. The values are rounded to the nearest integer. The radius is also rounded to the nearest integer.

Example:

>>> from machinevisiontoolbox import draw_circle, idisp
>>> import numpy as np
>>> img = np.zeros((1000, 1000), dtype='uint8')
>>> draw_circle(img, (300,400), 150, thickness=2, color=200)
>>> draw_circle(img, (500,700), 250, thickness=-1, color=50)  # filled
>>> draw_circle(img, (900,900), 200, thickness=-1, color=100)  # filled
>>> idisp(img)

(Source code, png, hires.png, pdf)

_images/graphics-2.png

Note

If image has multiple planes then color should have the same number of elements as the image has planes. If it is a scalar that value is used for each color plane. For a color image color can be a string color name.

Seealso:

plot_circle opencv.circle

draw_labelbox(image: ndarray, text: str, textcolor: Any = None, labelcolor: Any = None, font: str = 'simplex', fontsize: float = 0.9, fontheight: int | None = None, fontthickness: int = 2, position: str = 'topleft', **boxargs: Any) ndarray[source]#

Draw a labelled box in an image

Parameters:
  • image (ndarray(H,W), ndarray(H,W,P)) – image to draw into

  • text (str) – text label

  • textcolor (str, array_like(3), optional) – text color, defaults to black

  • labelcolor (str, array_like(3), optional) – label background color

  • position – place to draw the label: ‘topleft’ (default), ‘topright, ‘bottomleft’ or ‘bottomright’

  • font (str, optional) – OpenCV font, defaults to cv.FONT_HERSHEY_SIMPLEX

  • fontsize (float, optional) – OpenCV font scale, defaults to 0.3

  • fontheight (int, optional) – OpenCV font height in pixels, overrides fontsize if given

  • fontthickness (int, optional) – font thickness in pixels, defaults to 2

  • boxargs – arguments passed to draw_box

Raises:

TypeError – can’t draw color into a greyscale image

Returns:

passed image as modified

Return type:

ndarray(H,W), ndarray(H,W,P)

The position of the box is specified using the same arguments as for draw_box. The label font is specified using the same arguments as for draw_text. If labelcolor is specified it is used as the background color for the text label, otherwise the box color is used.

Example:

>>> from machinevisiontoolbox import draw_labelbox, idisp
>>> import numpy as np
>>> img = np.zeros((500, 500))
>>> draw_labelbox(img, "labelled box", lbwh=[100, 200, 400, 500], textcolor=0, labelcolor=100, color=200, thickness=2, fontsize=1)
>>> draw_labelbox(img, "another labelled box", position="bottomright", lbwh=[300, 450, 500, 400], textcolor=0, labelcolor=100, color=200, thickness=2, fontsize=1)
>>> idisp(img)

(Source code, png, hires.png, pdf)

_images/graphics-3.png

Note

If image has multiple planes then color, labelcolor and textcolor should have the same number of elements as the image has planes. If they are a scalar that value is used for each color plane. For a color image color can be a string color name.

Seealso:

draw_box, draw_text

draw_line(image: ndarray, start: tuple[float, float] | list[float] | ndarray, end: tuple[float, float] | list[float] | ndarray, color: Any, thickness: int = 1, antialias: bool = False) ndarray[source]#

Draw line in image

Parameters:
  • image (ndarray(H,W), ndarray(H,W,P)) – image to draw into, greyscale or color

  • start (array_like(2) int) – start coordinate (u,v)

  • end (array_like(2) int) – end coordinate (u,v)

  • color (scalar, array_like(3)) – color of line

  • thickness (int, optional) – width of line in pixels, defaults to 1

  • antialias (bool, optional) – use antialiasing, defaults to False

Raises:

TypeError – can’t draw color into a greyscale image

Returns:

passed image as modified

Return type:

ndarray(H,W), ndarray(H,W,P)

The coordinates can be tuples, lists or NumPy arrays. The values are rounded to the nearest integer.

Example:

>>> from machinevisiontoolbox import draw_line, idisp
>>> import numpy as np
>>> img = np.zeros((1000, 1000), dtype='uint8')
>>> draw_line(img, (100, 300), (700, 900), color=200, thickness=10)
>>> idisp(img)

(Source code, png, hires.png, pdf)

_images/graphics-4.png

Note

If image has multiple planes then color should have the same number of elements as the image has planes. If it is a scalar that value is used for each color plane. For a color image color can be a string color name.

Seealso:

plot_line opencv.line

draw_point(image: ndarray, pos: tuple[float, float] | list[float] | list[tuple[float, float]] | ndarray, marker: str = '+', text: Iterable[str] | str | None = None, color: Any = None, font: str = 'simplex', fontheight: int | None = None, fontsize: float = 0.3, fontthickness: int = 2) ndarray[source]#

Draw a marker in image

Parameters:
  • image (ndarray(H,W), ndarray(H,W,P)) – image to draw into, greyscale or color

  • pos (array_like(2), ndarray(2,n), list of 2-tuples) – position of marker

  • marker (str, optional) – marker character, defaults to ‘+’

  • text (str, optional) – text label, defaults to None

  • color (str or array_like(3), optional) – text color, defaults to None

  • font (str, optional) – OpenCV font, defaults to cv.FONT_HERSHEY_SIMPLEX

  • fontheight (int, optional) – height of font in pixels, defaults to None

  • fontsize (float, optional) – OpenCV font scale, defaults to 0.3

  • fontthickness (int, optional) – font thickness in pixels, defaults to 2

Raises:

TypeError – can’t draw color into a greyscale image

Returns:

passed image as modified

Return type:

ndarray(H,W), ndarray(H,W,P)

The text label is placed to the right of the marker, and vertically centred. The color of the marker can be different to the color of the text, the marker color is specified by a single letter in the marker string, eg. ‘b+’.

Multiple points can be marked if pos is a \(2 \times n\) array or a list of coordinate pairs. In this case:

  • if text is a string it is processed with text.format(i) where i is the point index (starting at zero). “{0}” within text will be substituted by the point index.

  • if text is a list, its elements are used to label the points

The font is specified by a string which selects a Hershey vector (stroke) font.

Font name

OpenCV font name

"simplex"

Hershey Roman simplex

"plain"

Hershey Roman plain

"duplex"

Hershey Roman duplex (double stroke)

"complex"

Hershey Roman complex

"triplex"

Hershey Romantriplex

"complex-small"

Hershey Roman complex (small)

"script-simplex"

Hershey script

"script-complex"

Hershey script complex

"italic"

Hershey italic

Note

Font size can be specified in two ways:

  • fontsize is the OpenCV font size scale factor as used by opencv.putText

  • fontheight is the height of the font in pixels, this overrides fontsize. The font scale is computed from fontheight using opencv.getFontScaleFromHeight

Note

The centroid of the marker character is very accurately positioned at the specified coordinate. The text label is placed to the right of the marker.

Note

If image has multiple planes then color should have the same number of elements as the image has planes. If it is a scalar that value is used for each color plane. For a color image color can be a string color name.

Example:

>>> from machinevisiontoolbox import draw_point, idisp
>>> import numpy as np
>>> img = np.zeros((1000, 1000), dtype='uint8')
>>> draw_point(img, (100, 300), '*', fontsize=1, color=200)
>>> draw_point(img, (500, 300), '*', 'labelled point', fontsize=1, color=200)
>>> draw_point(img, np.random.randint(1000, size=(2,10)), '+', 'point {0}', color=100, fontsize=0.8)
>>> idisp(img)

(Source code, png, hires.png, pdf)

_images/graphics-5.png
Seealso:

plot_point opencv.putText

draw_text(image: ndarray, pos: tuple[int, int] | list[int] | ndarray, text: str | None = None, color: Any = None, font: str = 'simplex', fontheight: int | None = None, fontsize: float = 0.3, fontthickness: int = 2, antialias: bool = False) ndarray[source]#

Draw text in image

Parameters:
  • image (ndarray(H,W), ndarray(H,W,P)) – image to draw into, greyscale or color

  • pos (array_like(2)) – position of text (u,v)

  • text (str) – text

  • color (scalar, array_like(3), str) – color of text

  • font (str, optional) – font name, defaults to “simplex”

  • fontheight (int, optional) – height of font in pixels, defaults to None

  • fontsize (float, optional) – OpenCV font scale, defaults to 0.3

  • fontthickness (int, optional) – font thickness in pixels, defaults to 2

  • antialias (bool, optional) – use antialiasing, defaults to False

Returns:

passed image as modified

Return type:

ndarray(H,W), ndarray(H,W,P)

The position corresponds to the bottom-left corner of the text box as seen in the image. The font is specified by a string which selects a Hershey vector (stroke) font.

Font name

OpenCV font name

'simplex'

Hershey Roman simplex

'plain'

Hershey Roman plain

'duplex'

Hershey Roman duplex (double stroke)

'complex'

Hershey Roman complex

'triplex'

Hershey Romantriplex

'complex-small'

Hershey Roman complex (small)

'script-simplex'

Hershey script

'script-complex'

Hershey script complex

'italic'

Hershey italic

Example:

>>> from machinevisiontoolbox import draw_text, idisp
>>> import numpy as np
>>> img = np.zeros((1000, 1000), dtype='uint8')
>>> draw_text(img, (100, 150), 'Hello world!', color=200, fontheight=60)
>>> idisp(img)

(Source code, png, hires.png, pdf)

_images/graphics-6.png

Note

Font size can be specified in two ways:

  • fontsize is the OpenCV font size scale factor as used by opencv.putText

  • fontheight is the height of the font in pixels, this overrides fontsize. The font scale is computed from fontheight using opencv.getFontScaleFromHeight

Note

If image has multiple planes then color should have the same number of elements as the image has planes. If it is a scalar that value is used for each color plane. For a color image color can be a string color name.

Seealso:

plot_text opencv.putText

plot_labelbox(text: str, textcolor: Any = None, labelcolor: Any = None, position: str = 'topleft', **boxargs: Any) Rectangle[source]#

Plot a labelled box using Matplotlib

Parameters:
  • text (str) – text label

  • textcolor (str, array_like(3), optional) – text color, defaults to None

  • labelcolor (str, array_like(3), optional) – label background color

  • position – place to draw the label: ‘topleft’ (default), ‘topright, ‘bottomleft’ or ‘bottomright’

  • boxargs – arguments passed to plot_box

Plot a box with a label above it. The position of the box is specified using the same arguments as for plot_box. The label font is specified using the same arguments as for plot_text. If labelcolor is specified it is used as the background color for the text label, otherwise the box color is used.

Example:

>>> from machinevisiontoolbox import plot_labelbox
>>> import numpy as np
>>> img = np.zeros((1000, 1000), dtype='uint8')
>>> idisp(img) # create a Matplotlib window
>>> plot_labelbox("labelled box", lbwh=[100, 250, 300, 400], color="yellow")
>>> plot_labelbox('another labelled box', position="bottomright", lbwh=[300, 450, 500, 400], color="red")

(Source code)

Seealso:

plot_box, plot_text