kwimage.im_draw

Module Contents

Functions

draw_text_on_image(img, text, org, **kwargs) Draws multiline text on an image using opencv
draw_clf_on_image(im, classes, tcx=None, probs=None, pcx=None, border=1) Draws classification label on an image.
draw_boxes_on_image(img, boxes, color=’blue’, thickness=1, box_format=None, colorspace=’rgb’) Draws boxes on an image.
draw_line_segments_on_image(img, pts1, pts2, color=’blue’, colorspace=’rgb’, thickness=1, **kwargs) Draw line segments between pts1 and pts2 on an image.
_broadcast_colors(color, num, img, colorspace) Determine if color applies a single color to all num items, or if it is
make_heatmask(probs, cmap=’plasma’, with_alpha=1.0, space=’rgb’, dsize=None) Colorizes a single-channel intensity mask (with an alpha channel)
make_orimask(radians, mag=None, alpha=1.0) Makes a colormap in HSV space where the orientation changes color and mag
make_vector_field(dx, dy, stride=0.02, thresh=0.0, scale=1.0, alpha=1.0, color=’red’, thickness=1, tipLength=0.1, line_type=’aa’) Create an image representing a 2D vector field.
draw_vector_field(image, dx, dy, stride=0.02, thresh=0.0, scale=1.0, alpha=1.0, color=’red’, thickness=1, tipLength=0.1, line_type=’aa’) Create an image representing a 2D vector field.
kwimage.im_draw.draw_text_on_image(img, text, org, **kwargs)

Draws multiline text on an image using opencv

Note

This function also exists in kwplot

The image is modified inplace. If the image is non-contiguous then this returns a UMat instead of a ndarray, so be carefull with that.

Parameters:
  • img (ndarray) – image to draw on (inplace)
  • text (str) – text to draw
  • org (tuple) – x, y location of the text string in the image. if bottomLeftOrigin=True this is the bottom-left corner of the text otherwise it is the top-left corner (default).
  • **kwargs – color (tuple): default blue thickneess (int): defaults to 2 fontFace (int): defaults to cv2.FONT_HERSHEY_SIMPLEX fontScale (float): defaults to 1.0 valign (str, default=bottom): either top, center, or bottom

References

https://stackoverflow.com/questions/27647424/

Example

>>> import kwimage
>>> img = kwimage.grab_test_image(space='rgb')
>>> img2 = kwimage.draw_text_on_image(img.copy(), 'FOOBAR', org=(0, 0), valign='top')
>>> assert img2.shape == img.shape
>>> assert np.any(img2 != img)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()
>>> kwplot.imshow(img2, fontScale=10)
>>> kwplot.show_if_requested()

Example

>>> import kwimage
>>> img = kwimage.grab_test_image(space='rgb')
>>> img2 = kwimage.draw_text_on_image(img, 'FOOBAR\nbazbiz\nspam', org=(0, 0), valign='top', border=2)
>>> img2 = kwimage.draw_text_on_image(img, 'FOOBAR\nbazbiz\nspam', org=(150, 0), valign='center', border=2)
>>> img2 = kwimage.draw_text_on_image(img, 'FOOBAR\nbazbiz\nspam', org=(300, 0), valign='bottom', border=2)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()
>>> kwplot.imshow(img2, fontScale=10)
>>> kwplot.show_if_requested()

Example

>>> # Ensure the function works with float01 or uint255 images
>>> import kwimage
>>> img = kwimage.grab_test_image(space='rgb')
>>> img = kwimage.ensure_float01(img)
>>> img2 = kwimage.draw_text_on_image(img, 'FOOBAR\nbazbiz\nspam', org=(0, 0), valign='top', border=2)
kwimage.im_draw.draw_clf_on_image(im, classes, tcx=None, probs=None, pcx=None, border=1)

Draws classification label on an image.

Works best with image chips sized between 200x200 and 500x500

Parameters:
  • im (ndarray) – the image
  • classes (Sequence | CategoryTree) – list of class names
  • tcx (int, default=None) – true class index if known
  • probs (ndarray) – predicted class probs for each class
  • pcx (int, default=None) – predicted class index. (if None but probs is specified uses argmax of probs)

Example

>>> import torch
>>> import kwarray
>>> import kwimage
>>> rng = kwarray.ensure_rng(0)
>>> im = (rng.rand(300, 300) * 255).astype(np.uint8)
>>> classes = ['cls_a', 'cls_b', 'cls_c']
>>> tcx = 1
>>> probs = rng.rand(len(classes))
>>> probs[tcx] = 0
>>> probs = torch.FloatTensor(probs).softmax(dim=0).numpy()
>>> im1_ = kwimage.draw_clf_on_image(im, classes, tcx, probs)
>>> probs[tcx] = .9
>>> probs = torch.FloatTensor(probs).softmax(dim=0).numpy()
>>> im2_ = kwimage.draw_clf_on_image(im, classes, tcx, probs)
>>> # xdoctest: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()
>>> kwplot.imshow(im1_, colorspace='rgb', pnum=(1, 2, 1), fnum=1, doclf=True)
>>> kwplot.imshow(im2_, colorspace='rgb', pnum=(1, 2, 2), fnum=1)
>>> kwplot.show_if_requested()
kwimage.im_draw.draw_boxes_on_image(img, boxes, color='blue', thickness=1, box_format=None, colorspace='rgb')

Draws boxes on an image.

Parameters:
  • img (ndarray) – image to copy and draw on
  • boxes (nh.util.Boxes) – boxes to draw
  • colorspace (str) – string code of the input image colorspace

Example

>>> import kwimage
>>> import numpy as np
>>> img = np.zeros((10, 10, 3), dtype=np.uint8)
>>> color = 'dodgerblue'
>>> thickness = 1
>>> boxes = kwimage.Boxes([[1, 1, 8, 8]], 'tlbr')
>>> img2 = draw_boxes_on_image(img, boxes, color, thickness)
>>> assert tuple(img2[1, 1]) == (30, 144, 255)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()  # xdoc: +SKIP
>>> kwplot.figure(doclf=True, fnum=1)
>>> kwplot.imshow(img2)
kwimage.im_draw.draw_line_segments_on_image(img, pts1, pts2, color='blue', colorspace='rgb', thickness=1, **kwargs)

Draw line segments between pts1 and pts2 on an image.

Parameters:
  • pts1 (ndarray) – xy coordinates of starting points
  • pts2 (ndarray) – corresponding xy coordinates of ending points
  • color (str | List) – color code or a list of colors for each line segment
  • colorspace (str, default=’rgb’) – colorspace of image
  • thickness (int, default=1)
  • lineType (int, default=cv2.LINE_AA)
Returns:

the modified image (inplace if possible)

Return type:

ndarray

Example

>>> from kwimage.im_draw import *  # NOQA
>>> pts1 = np.array([[2, 0], [2, 20], [2.5, 30]])
>>> pts2 = np.array([[10, 5], [30, 28], [100, 50]])
>>> img = np.ones((100, 100, 3), dtype=np.uint8) * 255
>>> color = 'blue'
>>> colorspace = 'rgb'
>>> img2 = draw_line_segments_on_image(img, pts1, pts2, thickness=2)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()  # xdoc: +SKIP
>>> kwplot.figure(doclf=True, fnum=1)
>>> kwplot.imshow(img2)

Example

>>> import kwimage
>>> pts1 = kwimage.Points.random(10).scale(512).xy
>>> pts2 = kwimage.Points.random(10).scale(512).xy
>>> img = np.ones((512, 512, 3), dtype=np.uint8) * 255
>>> color = kwimage.Color.distinct(10)
>>> img2 = kwimage.draw_line_segments_on_image(img, pts1, pts2, color=color)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()  # xdoc: +SKIP
>>> kwplot.figure(doclf=True, fnum=1)
>>> kwplot.imshow(img2)
kwimage.im_draw._broadcast_colors(color, num, img, colorspace)

Determine if color applies a single color to all num items, or if it is a list of colors for each item. Return as a list of colors for each item.

Todo

  • [ ] add as classmethod of kwimage.Color

Example

>>> img = (np.random.rand(512, 512, 3) * 255).astype(np.uint8)
>>> colorspace = 'rgb'
>>> color = color_str_list = ['red', 'green', 'blue']
>>> color_str = 'red'
>>> num = 3
>>> print(_broadcast_colors(color_str_list, num, img, colorspace))
>>> print(_broadcast_colors(color_str, num, img, colorspace))
>>> colors_tuple_list = _broadcast_colors(color_str_list, num, img, colorspace)
>>> print(_broadcast_colors(colors_tuple_list, num, img, colorspace))
>>> #
>>> # FIXME: This case seems broken
>>> colors_ndarray_list = np.array(_broadcast_colors(color_str_list, num, img, colorspace))
>>> print(_broadcast_colors(colors_ndarray_list, num, img, colorspace))
kwimage.im_draw.make_heatmask(probs, cmap='plasma', with_alpha=1.0, space='rgb', dsize=None)

Colorizes a single-channel intensity mask (with an alpha channel)

Parameters:
  • probs (ndarray) – 2D probability map with values between 0 and 1
  • cmap (str) – mpl colormap
  • with_alpha (float) – between 0 and 1, uses probs as the alpha multipled by this number.
  • space (str) – output colorspace
  • dsize (tuple) – if not None, then output is resized to W,H=dsize
SeeAlso:
kwimage.overlay_alpha_images

Example

>>> # xdoc: +REQUIRES(module:matplotlib)
>>> probs = np.tile(np.linspace(0, 1, 10), (10, 1))
>>> heatmask = make_heatmask(probs, with_alpha=0.8, dsize=(100, 100))
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.imshow(heatmask, fnum=1, doclf=True, colorspace='rgb')
>>> kwplot.show_if_requested()
kwimage.im_draw.make_orimask(radians, mag=None, alpha=1.0)

Makes a colormap in HSV space where the orientation changes color and mag changes the saturation/value.

Parameters:
  • radians (ndarray) – orientation in radians
  • mag (ndarray) – magnitude (must be normalized between 0 and 1)
  • alpha (float | ndarray) – if False or None, then the image is returned without alpha if a float, then mag is scaled by this and used as the alpha channel if an ndarray, then this is explicilty set as the alpha channel
Returns:

an rgb / rgba image in 01 space

Return type:

ndarray[float32]

SeeAlso:
kwimage.overlay_alpha_images

Example

>>> # xdoc: +REQUIRES(module:matplotlib)
>>> x, y = np.meshgrid(np.arange(64), np.arange(64))
>>> dx, dy = x - 32, y - 32
>>> radians = np.arctan2(dx, dy)
>>> mag = np.sqrt(dx ** 2 + dy ** 2)
>>> orimask = make_orimask(radians, mag)
>>> # xdoc: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.imshow(orimask, fnum=1, doclf=True, colorspace='rgb')
>>> kwplot.show_if_requested()
kwimage.im_draw.make_vector_field(dx, dy, stride=0.02, thresh=0.0, scale=1.0, alpha=1.0, color='red', thickness=1, tipLength=0.1, line_type='aa')

Create an image representing a 2D vector field.

Parameters:
  • dx (ndarray) – grid of vector x components
  • dy (ndarray) – grid of vector y components
  • stride (int | float) – sparsity of vectors, int specifies stride step in pixels, a float specifies it as a percentage.
  • thresh (float) – only plot vectors with magnitude greater than thres
  • scale (float) – multiply magnitude for easier visualization
  • alpha (float) – alpha value for vectors. Non-vector regions receive 0 alpha (if False, no alpha channel is used)
  • color (str | tuple | kwimage.Color) – RGB color of the vectors
  • thickness (int, default=1) – thickness of arrows
  • tipLength (float, default=0.1) – fraction of line length
  • line_type (int) – either cv2.LINE_4, cv2.LINE_8, or cv2.LINE_AA
Returns:

vec_img: an rgb/rgba image in 0-1 space

Return type:

ndarray[float32]

SeeAlso:
kwimage.overlay_alpha_images

DEPRECATED USE: draw_vector_field instead

Example

>>> x, y = np.meshgrid(np.arange(512), np.arange(512))
>>> dx, dy = x - 256.01, y - 256.01
>>> radians = np.arctan2(dx, dy)
>>> mag = np.sqrt(dx ** 2 + dy ** 2)
>>> dx, dy = dx / mag, dy / mag
>>> img = make_vector_field(dx, dy, scale=10, alpha=False)
>>> # xdoctest: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()
>>> kwplot.imshow(img)
>>> kwplot.show_if_requested()
kwimage.im_draw.draw_vector_field(image, dx, dy, stride=0.02, thresh=0.0, scale=1.0, alpha=1.0, color='red', thickness=1, tipLength=0.1, line_type='aa')

Create an image representing a 2D vector field.

Parameters:
  • image (ndarray) – image to draw on
  • dx (ndarray) – grid of vector x components
  • dy (ndarray) – grid of vector y components
  • stride (int | float) – sparsity of vectors, int specifies stride step in pixels, a float specifies it as a percentage.
  • thresh (float) – only plot vectors with magnitude greater than thres
  • scale (float) – multiply magnitude for easier visualization
  • alpha (float) – alpha value for vectors. Non-vector regions receive 0 alpha (if False, no alpha channel is used)
  • color (str | tuple | kwimage.Color) – RGB color of the vectors
  • thickness (int, default=1) – thickness of arrows
  • tipLength (float, default=0.1) – fraction of line length
  • line_type (int) – either cv2.LINE_4, cv2.LINE_8, or cv2.LINE_AA
Returns:

The image with vectors overlaid. If image=None, then an

rgb/a image is created and returned.

Return type:

ndarray[float32]

Example

>>> import kwimage
>>> width, height = 512, 512
>>> image = kwimage.grab_test_image(dsize=(width, height))
>>> x, y = np.meshgrid(np.arange(height), np.arange(width))
>>> dx, dy = x - width / 2, y - height / 2
>>> radians = np.arctan2(dx, dy)
>>> mag = np.sqrt(dx ** 2 + dy ** 2) + 1e-3
>>> dx, dy = dx / mag, dy / mag
>>> img = kwimage.draw_vector_field(image, dx, dy, scale=10, alpha=False)
>>> # xdoctest: +REQUIRES(--show)
>>> import kwplot
>>> kwplot.autompl()
>>> kwplot.imshow(img)
>>> kwplot.show_if_requested()