『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
注意事项:
- 绘图操作会直接对传入的图像 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