图形绘制(Drawer)

数据处理中常见的一类工作就是对标注结果的可视化处理,通过将标注的点、线、矩形、多边形等图形绘制到原始 图像上,使得对标注效果可以做快速判断。另一方面,相比于坐标点集合的JSON文件,有些人更偏爱使用 mask图进行图像识别方面的训练,换句话说,这要求将标注结果绘制到一张与原始图像同样大小的黑色的 画布上。

然而在实际情况中,同一张图片往往包含多种图形的标注,例如街景标注中,可能既包含车道线(线),人、车( 多边形)的标注,也需要框出所有的交通灯和交通标志(矩形框)。而且,在绘制的时候,根据标注的实际情况, 绘制方法可能是轮廓也可能是填充。如何既提供通用快速的绘制接口,又能根据实际情况进行扩展(改变绘制方法 、颜色、粗细等),就是 toolbox.image.drawer 的设计目的。

因此,我们将 Shape(图形) 这一对象抽象出来,提供了验证和绘制的接口,并且提供默认的绘制实现, 调用绘制接口在图上进行绘制则由 Painter(绘制器) 完成。开发人员只需要关注图形的初始化和绘制方法 的实现即可。

Shapes(图形)

Shapes 是对被绘制图形的抽象,提供了一系列的绘制图形的基础属性如形状、颜色、线宽等,也提供 了对坐标值的格式进行验证、标准化、绘制的方法。

class moose.toolbox.image.drawer.BaseShape(coordinates, label, color=None, filled=None, thickness=None, **options)

BaseShape是所有图形类的基类,它定义了Shape子类应该包含的属性、需要实现的接口并且为通用 方法提供了默认实现。

参数:
  • coordinates (list) – 表示图形的坐标点的集合。对于不同的图形可能有不同的格式要求,例如对于点, 要求 coordinates 的值是包含两个元素的列表 [x, y] ,对于多边形,要求是 [[x1, y1], [x2, y2] ... [xn, yn], [x1, y1]] 的格式,等等。对于具体格式的检查在 _is_valid_coordinates() 中有相应的实现。
  • label (str) – 该图形对应物体的标签。
  • color (tuple) – 该图形被绘制时的颜色,可以是一个整型(灰度图)也可以是包含三个整型的元组(RGB)。 默认值是 default_color = settings.DEFAULT_COLOR
  • filled (boolean) – 该图形被绘制时是采用内部填充的方式还是绘制轮廓的方式,默认值根据类变量 drawn_filled 决定,对于线、点等图形不发挥作用。
  • thickness (int) – 该图形被绘制时的线的粗细,默认值为 default_thickness = settings.DEFAULT_THICKNESS
  • options (dict) – 其他的可选项参数。
type

类变量,表征该绘制图形的名称,如 Polygon,Point,Rectangle 等。

_is_list_of_pairs(points)

@classmethod

参数:points (tuple) – 坐标点。

返回bool值,该方法通过调用is_valid_format()和is_valid_value()来对输入点进行校验。

is_valid_format(point)

@classmethod

参数:point (tuple) – 坐标点。

返回bool值,该方法用来判断输入点的类型是否为列表或者元祖,且长度是否为2,若满足则返回 True ,否则为 False

is_valid_value(point)

@classmethod

参数:point (tuple) – 坐标点。

返回bool值,该方法用来判断输入点中元素是否是整数(或者为可以转换成整数的字符串)。

_equal_points(p1, p2)

@classmethod

参数:
  • p1 (tuple) – 坐标点。
  • p2 (tuple) – 坐标点。

返回bool值,该方法用来判断输入的两个点是否完全相等(x,y是否分别对应相等)。

_is_valid_coordinates(coordinates)
参数:coordinates (list) – 坐标列表。

对传入的坐标参数进行校验,默认返回 True ,子类根据具体图形实现自己的校验方式。

normalize(coordinates)
参数:coordinates (list) – 表示图形的坐标点的集合。

该方法是将输入的坐标进行格式化(将其元素中的浮点数转换为 int ,并将列表转换为 tuple )。返回一个内部元素为元祖的列表。

set_color(color)
参数:color (str) – 颜色。

设置绘制颜色,如果输入的color为 None,则使用默认的颜色,否则使用输入的颜色。

color()

@property

返回该图形的绘制颜色。 需要注意的是,因为 OpenCV 中(R, G, B)是反向的,如果 self._colorlist 或者 tuple 则对其逆序。

draw_on(im)
参数:im (object) – OpenCV 图形对象。

图形被绘制的主要接口,定义了绘制时的默认行为,如果 self._filledTrue , 则使用填充方式绘制,否则使用绘制轮廓。

_fill(im)

abstract

参数:im (object) – OpenCV 图形对象。

该方法用来在被标注对象文件上使用图像上的颜色填充形状,为预留接口,子类必须继承并且实现该方法。

_outline(im)

abstract

参数:im (object) – OpenCV 图形对象。

该方法用来在被标注对象文件上绘制轮廓的形状,为预留接口,子类必须继承并且实现该方法。

class moose.toolbox.image.drawer.Point(BaseShape)

Point 是BaseShape的子类,它定义了图形 的具体实现。

type

默认值为 “Point”

radius

定义绘制图形点的半径,默认值为 settings.DRAWER_RADIUS

_is_valid_coordinates(coordinates)
参数:coordinates (tuple) – 表示图形点的坐标点的集合。

判断输入格式是否为 [x, y] 的形式。

draw_on(im)
参数:im (object) – OpenCV 图形对象。

调用 cv2.circle 进行绘制,具体实现如下::

cv2.circle(im, self._coordinates, self.radius, self.color, -1)
class moose.toolbox.image.drawer.LineString(BaseShape)

LineString 是BaseShape的子类,它定义了图形 线 的具体实现。

type

默认值为 “LineString”

_is_valid_coordinates(coordinates)
参数:coordinates (list) – 表示图形线的坐标点的集合。

判断坐标是否按照 [[x0, y0], [x1, y1]][[x0, y0], [x1, y1], [x2, y2]] 的格式传入。

draw_on(im)
参数:im (object) – OpenCV 图形对象。

调用 cv2.line 进行绘制,具体实现如下::

for start, end in zip(self._coordinates[:-1], self._coordinates[1:]):
    cv2.line(im, start, end, self.color, self._thickness)
class moose.toolbox.image.drawer.Polygon(BaseShape)

Polygon 是BaseShape的子类,它定义了图形 多边形 的具体实现。与 线 不同的是,在绘制时既可以填充也可以绘制轮廓,默认情况下,我们使用填充的方式进行绘制。

type

默认值为 “Polygon”

is_closed

定义该类绘制图形的形状是否是封闭的。

drawn_filled

默认为 True ,即绘制时默认使用填充的方式。

_is_valid_coordinates(coordinates)
参数:coordinates (list) – 坐标。

判断输入点是否是 [[x1, y1], [x2, y2] ... [xn, yn], [x1, y1]] 的格式。

to_nparray()

返回将坐标点转换成 np.array 对象的表示,其中每个元素类型为 np.int32

_fill(im)

调用 cv2.fillPoly 进行绘制,具体实现如下::

cv2.fillPoly(im, [self.to_nparray()], self.color)
_outline(im)

调用 cv2.polylines 进行绘制,具体实现如下::

cv2.polylines(im, [self.to_nparray()], self.is_closed, self.color, self._thickness)
class moose.toolbox.image.drawer.Rectangle(BaseShape)

Rectangle 是BaseShape的子类,它定义了图形 矩形 的具体实现。与 线 不同的是,在绘制时既可以填充也可以绘制轮廓,默认情况下,我们使用绘制轮廓的方式进行绘制。

type

默认值为 “Rectangle”

drawn_filled=False

默认为 False ,即绘制时默认使用绘制轮廓的方式。

_is_valid_coordinates(coordinates)
参数:coordinates (list) – 坐标。

判断输入点是否为 [[x1, y1], [x2, y2]] 的形式。

from_region(region, label, **options)

@classmethod

参数:
  • region (list) – 坐标。
  • label (str) – 标签。
  • options (dict) – 其他可选参数。

当坐标点格式为 [x, y, w, h] 调用此类方法来实例化。

from_points(points, label, **options)

@classmethod

参数:
  • coordinates (tuple) – 坐标。
  • label (str) – 标签。
  • options (dict) – 其他可选参数。

当坐标点格式为 [[x1, y1], [x1, y2], [x2, y2,], [x2, y1], [x1, y1]] 调用此类方法来实例化。

to_points()

输出按照 [[x1, y1], [x1, y2], [x2, y2,], [x2, y1], [x1, y1]] 形式的坐标点表示。

_outline(im)

调用 cv2.rectangle 进行绘制,具体实现如下::

cv2.rectangle(im, tuple(self._coordinates[0]), tuple(self._coordinates[1]), self.color, self._thickness)
_fill(im)

调用 cv2.rectangle 进行绘制,具体实现如下::

cv2.rectangle(im, tuple(self._coordinates[0]), tuple(self._coordinates[1]), self.color, -1)

Painter(绘制器)

class moose.toolbox.image.drawer.GeneralPainter(image_path, pallet=None, autofill=False, use_default=False, persistent=True)

GeneralPainter 提供了整合多个图形,对图像按照多种方式进行绘制的能力。为 GeneralPainter 提供图片的完整路径和待绘制的 Shapes 列表,即可输出效果图(draw),掩模图(masking) 和合成图(blend)。对于输出图形的颜色,既可以在实例化 Shapes 的时候定义,也可以向 GeneralPainter 提供一个pallet(调色板),指定每个label和color的映射关系,来控制 图形绘制颜色的选择。

参数:
  • image_path (str) – 图片路径,如果不存在会抛出 IOError
  • pallet (dict) – 标签和颜色的映射表,提供了 shape 的label对应的颜色。
  • autofill (bool) – 当 shape 的label在 pallet 中不存在时,是否随机生成 一个颜色,如果为 False 时,会抛出 ImproperlyConfigured
  • use_default (bool) – 为 True 时,使用 shape 的color属性的值作为绘制的 颜色。
  • persistent (bool) – 当 autofillTrue 时,是否所有图形绘制使用相同的 label到color的映射。
shape_line_cls

指定实例化图形 线 的类,默认为 LineString

shape_point_cls

指定实例化图形 的类,默认为 Point

shape_polygon_cls

指定实例化图形 多边形 的类,默认为 Polygon

shape_rectangle_cls

指定实例化图形 矩形 的类,默认为 Rectangle

get_color(label)
参数:label (str) – 图形标签

返回图形标签对应的颜色,该值受 palletautofilluse_default 的影响,有以下三种可能:

  1. use_defaultTrue 的时候,返回 None
  2. use_defaultFalsepallet 包含该label对应的color,返回该值;
  3. use_defaultFalsepallet 不包含该label,且 autofillTrue 时,随机返回一种颜色;
add_color(label, color)
参数:
  • label (str) – 图形标签
  • color (tuple) – 颜色

添加一对标签和颜色的对应关系到 pallet 中。

update_pallet(pallet)
参数:pallet (dict) – 标签和颜色的映射表

更新 pallet 的标签和颜色的映射。

add_shape(shape)
参数:shape (object) – 图形对象

添加一个待绘制的图形对象。

from_shapes(shapes)
参数:shapes (list) – 图形对象列表或生成器

添加多个待绘制的图形对象。

clear()

清空待绘制的图形对象列表。

add_line(p1, p2, label, **options)
参数:
  • p1 (tuple) – 点坐标
  • p2 (tuple) – 点坐标
  • label (str) – 图形标签
  • options (dict) – 参数

实例化并添加线图形对象。

add_point(p, lable, **options)
参数:
  • p (tuple) – 点坐标
  • label (str) – 图形标签
  • options (dict) – 参数

实例化并添加点图形对象。

add_rectangle(p1, p2, label, **options)
参数:
  • p1 (tuple) – 点坐标
  • p2 (tuple) – 点坐标
  • label (str) – 图形标签
  • options (dict) – 参数

实例化并添加矩形图形对象。

add_polygon(pts, label, **options)
参数:
  • pts (tuple) – 点坐标
  • label (str) – 图形标签
  • options (dict) – 参数

实例化并添加多边形图形对象。

render(canvas)
参数:canvas (object) – 待绘制的目标图像文件

绘制图形列表中的图形到canvas上::

for shape in self._shapes:
    shape.set_color(self.get_color(shape._label))
    shape.draw_on(canvas)
return canvas
draw(filename)
参数:filename (str) – 图片对象名称

将图形列表中的图形绘制到原始图像中。

masking(filename)
参数:filename (str) – 图片对象名称

将图形列表中的图形绘制到与原始图像等尺寸的所有值为 (0, 0, 0) 的图像上。

blend(filename, alpha=0.7, gamma=0.0)
参数:
  • filename (str) – 图片对象名称
  • alpha (int) – 第一个数组元素的权重值
  • gamma (int) – 标量,在按位与计算中将标量加到每个和中,调整整体颜色

叠加原始图片和mask图,按照如下公式生成::

dst = alpha * src1 + (1 - alpha) * src2 + gamma