OpenCV 例程 300篇254.OpenCV 绘制图像标记

Posted YouCans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV 例程 300篇254.OpenCV 绘制图像标记相关的知识,希望对你有一定的参考价值。

『youcans 的 OpenCV 例程300篇 - 总目录』


【youcans 的 OpenCV 例程 300篇】254. OpenCV 绘制标记


7.1 绘图函数基本参数

OpenCV提供了绘图功能,可以在图像上绘制直线、矩形、圆、椭圆等各种几何图形。

函数 cv.line()、cv.rectangle()、cv.circle()、cv.polylines() 等分别用来在图像中绘制直线、矩形、圆形、多边形等几何形状,这些绘图函数中有一些的设置参数,介绍如下:

  • img:输入输出图像,格式不限
  • color:绘图线条的颜色,(b,g,r) 格式的元组,或者表示灰度值的标量
    • thickness:绘制线条的粗细,默认值 1px,-1 表示内部填充
  • lineType:绘制线段的线性,默认为 LINE_8
    • cv.FILLED:内部填充(实心图形)
    • cv.LINE_4:4 邻接线型
    • cv.LINE_8:8 邻接线型
    • cv.LINE_AA:抗锯齿线型,图像更平滑
  • shift:点坐标的小数位数,默认为 0

7.2 绘制标记

函数原型:

函数 cv.drawMarker 用来在图像上的指定位置绘制标记。

cv.drawMarker(img, position, color[, markerType=MARKER_CROSS, markerSize=20, thickness=1, line_type=8]) → img

参数说明:

  • img:输入输出图像,允许单通道灰度图像或多通道彩色图像
  • position:标记点的坐标,(x1, y1) 格式的元组
  • color:绘制标记的颜色
  • markerType:标记类型,默认为 cv.MARKER_CROSS(十字标记)
    • cv.MARKER_CROSS:十字标记(类似加号),+
    • cv.MARKER_TILTED_CROSS:,倾斜的十字标记(类似乘号), × \\times ×
    • cv.MARKER_STAR:星形标记(类似米字), ★ \\bigstar
    • cv.MARKER_DIAMOND:钻石菱形标记, ⋄ \\diamond
    • cv.MARKER_SQUARE:方块标记, □ \\Box
    • cv.MARKER_TRIANGLE_UP:上三角标记, △ \\triangle
    • cv.MARKER_TRIANGLE_DOWN:下三角标记, ▽ \\triangledown
  • markerSize:标记的轴向长度,默认值 20pixels

注意事项:

  1. 绘图操作会直接对传入的图像 img 进行修改,是否接受函数返回值都可以。如果要保持输入图像不变则要用 img.copy() 进行复制。

例程 A4.15:在图像上绘制标记

本例程示例在图像上绘制标记。

    # A4.15 绘制标记
    img = np.ones((600, 800, 3), np.uint8)*205
    for i in range(7):  # 7 种标记
        cx = 100*(i+1)
        color = (0,0,255)
        cv.drawMarker(img, (cx, 100), color, markerType=i, markerSize=10)
        cv.drawMarker(img, (cx, 200), color, markerType=i, markerSize=20)
        cv.drawMarker(img, (cx, 300), color, markerType=i, markerSize=30)
        cv.drawMarker(img, (cx, 400), color, markerType=i, markerSize=40)
        cv.drawMarker(img, (cx, 500), color, markerType=i, markerSize=50)

    plt.figure(figsize=(9, 4))
    plt.subplot(121), plt.title("Draw marker"), plt.axis('off')
    plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.subplot(122), plt.title("Draw marker"), plt.axis('off')
    plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()


** 延伸阅读**

7.3 绘制直线

函数原型

函数 cv.line() 用来在图像中绘制直线,函数 cv.arrowedLine() 用来在图像中绘制带箭头直线。

cv.line(img, pt1, pt2, color[, thickness=1, lineType=LINE_8, shift=0]) → img
cv.arrowedLine(img, pt1, pt2, color[, thickness=1, line_type=8, shift=0, tipLength=0.1]) → img

函数 cv.line() 绘制图像中点 pt1 与点 pt2 之间的线段,函数 cv.arrowedLine() 绘制图像中点 pt1 与点 pt2 之间的带箭头线段。

参数说明:

  • img:输入输出图像,允许单通道灰度图像或多通道彩色图像
  • pt1:线段第一个点的坐标,(x1, y1)
  • pt2:线段第二个点的坐标,(x2, y2)
  • tipLength:箭头部分长度与线段长度的比例,默认为 0.1

7.4 绘制矩形

函数原型:

函数 cv.rectangle() 用来在图像上绘制垂直于图像边界的矩形。

cv.rectangle(img, pt1, pt2, color[, thickness=1, lineType=LINE_8, shift=0]) → img
cv.rectangle(img, rec, color[, thickness=1, lineType=LINE_8, shift=0]) → img

参数说明:

  • img:输入输出图像,允许单通道灰度图像或多通道彩色图像

  • pt1:矩阵第一个点的坐标,(x1, y1) 格式的元组

  • pt2:与 pt1 成对角的矩阵第二个点的坐标,(x2, y2) 格式的元组

  • color:绘图线条的颜色,(b,g,r) 格式的元组,或者表示灰度值的标量

  • thickness:绘制矩形的线宽,默认值 1px,负数表示矩形内部填充

  • lineType:绘制线段的线性,默认为 LINE_8

  • shift:点坐标的小数位数,默认为 0


例程 A4.3:在图像上绘制倾斜的矩形

cv.rectangle 只能在图像上绘制垂直于边界的矩形。如果需要绘制倾斜的矩形,则要获得倾斜矩形的各个顶点坐标,通过绘制直线构造成为闭合的矩形。

    # A4.3 在图像上绘制倾斜的矩形
    height, width, channels = 600, 400, 3
    img = np.ones((height, width, channels), np.uint8)*192  # 创建黑色图像 RGB=0

    # 围绕矩形中心旋转
    x, y, w, h = (100, 200, 200, 100)  # 左上角坐标 (x,y), 宽度 w,高度 h
    cx, cy = x+w//2, y+h//2  # 矩形中心
    img1 = img.copy()
    cv.circle(img1, (cx,cy), 4, (0,0,255), -1)  # 旋转中心
    angle = [15, 30, 45, 60, 75, 90]  # 旋转角度,顺时针方向
    for i in range(len(angle)):
        ang = angle[i] * np.pi / 180
        x1 = int(cx + (w/2)*np.cos(ang) - (h/2)*np.sin(ang))
        y1 = int(cy + (w/2)*np.sin(ang) + (h/2)*np.cos(ang))
        x2 = int(cx + (w/2)*np.cos(ang) + (h/2)*np.sin(ang))
        y2 = int(cy + (w/2)*np.sin(ang) - (h/2)*np.cos(ang))
        x3 = int(cx - (w/2)*np.cos(ang) + (h/2)*np.sin(ang))
        y3 = int(cy - (w/2)*np.sin(ang) - (h/2)*np.cos(ang))
        x4 = int(cx - (w/2)*np.cos(ang) - (h/2)*np.sin(ang))
        y4 = int(cy - (w/2)*np.sin(ang) + (h/2)*np.cos(ang))
        color = (30*i, 0, 255-30*i)
        cv.line(img1, (x1,y1), (x2,y2), color)
        cv.line(img1, (x2,y2), (x3,y3), color)
        cv.line(img1, (x3,y3), (x4,y4), color)
        cv.line(img1, (x4,y4), (x1,y1), color)

    # 围绕矩形左上顶点旋转
    x, y, w, h = (200, 200, 200, 100)  # 左上角坐标 (x,y), 宽度 w,高度 h
    img2 = img.copy()
    cv.circle(img2, (x, y), 4, (0,0,255), -1)  # 旋转中心
    angle = [15, 30, 45, 60, 75, 90, 120, 150, 180, 225]  # 旋转角度,顺时针方向
    for i in range(len(angle)):
        ang = angle[i] * np.pi / 180
        x1, y1 = x, y
        x2 = int(x + w * np.cos(ang))
        y2 = int(y + w * np.sin(ang))
        x3 = int(x + w * np.cos(ang) - h * np.sin(ang))
        y3 = int(y + w * np.sin(ang) + h * np.cos(ang))
        x4 = int(x - h * np.sin(ang))
        y4 = int(y + h * np.cos(ang))
        color = (30 * i, 0, 255 - 30 * i)
        cv.line(img2, (x1, y1), (x2, y2), color)
        cv.line(img2, (x2, y2), (x3, y3), color)
        cv.line(img2, (x3, y3), (x4, y4), color)
        cv.line(img2, (x4, y4), (x1, y1), color)

    plt.figure(figsize=(9, 6))
    plt.subplot(121), plt.title("img1"), plt.axis('off')
    plt.imshow(cv.cvtColor(img1, cv.COLOR_BGR2RGB))
    plt.subplot(122), plt.title("img2"), plt.axis('off')
    plt.imshow(cv.cvtColor(img2, cv.COLOR_BGR2RGB))
    plt.show()

例程结果:


7.5 绘制圆形

函数原型:

函数 cv.circle() 用来在图像上绘制圆形。

cv.circle(img, center, radius, color[, thickness=1, lineType=LINE_8, shift=0]) → img

参数说明:

  • img:输入输出图像,允许单通道灰度图像或多通道彩色图像

  • center:圆心点的坐标,(x, y) 格式的元组

  • radius:圆的半径,整数

  • color:绘图线条的颜色,(b,g,r) 格式的元组,或者表示灰度值的标量

  • thickness:绘制矩形的线宽,默认值 1px,负数表示矩形内部填充

  • lineType:绘制线段的线性,默认为 LINE_8

  • shift:点坐标的小数位数,默认为 0


7.4 绘制椭圆

函数原型:

函数 cv.ellipse() 用来在图像上绘制椭圆轮廓、填充椭圆、椭圆弧或填充椭圆扇区。

cv.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness=1, lineType=LINE_8, shift=0]) → img
cv.ellipse(img, box, color[, thickness=1, lineType=LINE_8]) → img

参数说明:

  • img:输入输出图像,允许单通道灰度图像或多通道彩色图像
  • center:椭圆中心点的坐标,(x, y) 格式的元组
  • axes:椭圆半轴长度,(hfirst, hsecond) 格式的元组
  • angle: 椭圆沿 x轴方向的旋转角度(角度制,顺时针方向)
  • startAngle:绘制的起始角度
  • endAngle:绘制的终止角度
  • box:通过 RotatedRec 类表示椭圆
  • color:绘图线条的颜色,(b,g,r) 格式的元组,或者表示灰度值的标量
  • thickness:绘制矩形的线宽,默认值 1px,负数表示矩形内部填充
  • lineType:绘制线段的线性,默认为 LINE_8
  • shift:点坐标的小数位数,默认为 0
    # A4.6 基于多段线绘制近似椭圆
    img = np.ones((400, 600, 3), np.uint8)*224

    cx, cy = 100, 150
    halfAxesLength = (70, 40)
    angle, startAng, endAng = 30, 0, 360
    delta = [10, 20, 30, 40]
    for i in range(len(delta)):
        color = (i*60, i*60, 255-i*60)
        pts = cv.ellipse2Poly((cx+140*i, cy), halfAxesLength, angle, startAng, endAng, delta[i])  # (351,2)
        points = np.array(pts)
        cv.polylines(img, [points], True, color, thickness=1)  # 绘制近似多边形
        points[:,1] += 160
        cv.fillPoly(img, [points], color)  # 绘制填充近似多边形
        text1 = "delta=".format(delta[i])
        text2 = "num=".format(pts.shape)
        cv.putText(img, text1, (140*i+25, 30), cv.FONT_HERSHEY_SIMPLEX, 0.5, 255)
        cv.putText(img, text2, (140*i+25, 50), cv.FONT_HERSHEY_SIMPLEX, 0.5, 255)
        print(pts.shape, points.shape)

    plt.figure(figsize=(9, 6))
    plt.title("Polygon approximated ellipse"), plt.axis('off')
    plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.show()

【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/128466627)
Copyright 2022 youcans, XUPT
Crated:2023-1-2

以上是关于OpenCV 例程 300篇254.OpenCV 绘制图像标记的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 例程 300篇255.OpenCV 实现图像拼接

OpenCV 例程 300篇255.OpenCV 实现图像拼接

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测

OpenCV 例程300篇238. OpenCV 中的 Harris 角点检测

OpenCV 例程 300篇241. 尺度不变特征变换(SIFT)

OpenCV 例程 300篇241. 尺度不变特征变换(SIFT)