目标
在本文中将学习如何:
● 使用OpenCV函数 line() 画一条线
● 使用OpenCV函数 ellipse() 绘制椭圆
● 使用OpenCV函数 rectangle() 绘制一个矩形
● 使用OpenCV函数 circle() 绘制一个圆
● 使用OpenCV函数 fillPoly() 绘制填充多边形
代码
import cv2 as cvimport numpy as npW = 400def my_ellipse(img, angle):thickness = 2line_type = 8cv.ellipse(img,(W // 2, W // 2),(W // 4, W // 16),angle,0,360,(255, 0, 0),thickness,line_type)def my_filled_circle(img, center):thickness = -1line_type = 8cv.circle(img,center,W // 32,(0, 0, 255),thickness,line_type)def my_polygon(img):line_type = 8# 创建一些点ppt = np.array([[W / 4, 7 * W / 8], [3 * W / 4, 7 * W / 8],[3 * W / 4, 13 * W / 16], [11 * W / 16, 13 * W / 16],[19 * W / 32, 3 * W / 8], [3 * W / 4, 3 * W / 8],[3 * W / 4, W / 8], [26 * W / 40, W / 8],[26 * W / 40, W / 4], [22 * W / 40, W / 4],[22 * W / 40, W / 8], [18 * W / 40, W / 8],[18 * W / 40, W / 4], [14 * W / 40, W / 4],[14 * W / 40, W / 8], [W / 4, W / 8],[W / 4, 3 * W / 8], [13 * W / 32, 3 * W / 8],[5 * W / 16, 13 * W / 16], [W / 4, 13 * W / 16]], np.int32)ppt = ppt.reshape((-1, 1, 2))cv.fillPoly(img, [ppt], (255, 255, 255), line_type)# 如果只画线,请使用:# cv.polylines(img, [ppt], True, (255, 0, 255), line_type)def my_line(img, start, end):thickness = 2line_type = 8cv.line(img,start,end,(0, 0, 0),thickness,line_type)atom_window = "Drawing 1: Atom"rook_window = "Drawing 2: Rook"# 创建黑色空白图像size = W, W, 3atom_image = np.zeros(size, dtype=np.uint8)rook_image = np.zeros(size, dtype=np.uint8)# 1. 画原子# ------------------# 1.a. 创建椭圆my_ellipse(atom_image, 90)my_ellipse(atom_image, 0)my_ellipse(atom_image, 45)my_ellipse(atom_image, -45)# 1.b. 创建圆my_filled_circle(atom_image, (W // 2, W // 2))# 2. 画(象棋)车# ------------------# 2.a. 创建凸多边形my_polygon(rook_image)cv.rectangle(rook_image,(0, 7 * W // 8),(W, W),(0, 255, 255),-1,8)# 2.b. 画一些线my_line(rook_image, (0, 15 * W // 16), (W, 15 * W // 16))my_line(rook_image, (W // 4, 7 * W // 8), (W // 4, W))my_line(rook_image, (W // 2, 7 * W // 8), (W // 2, W))my_line(rook_image, (3 * W // 4, 7 * W // 8), (3 * W // 4, W))cv.imshow(atom_window, atom_image)cv.moveWindow(atom_window, 0, 200)cv.imshow(rook_window, rook_image)cv.moveWindow(rook_window, W, 200)cv.waitKey(0)cv.destroyAllWindows()
代码解释
由于计划绘制两个示例(一个原子和一个车),我们必须创建两个图像和两个窗口来显示它们。
# 窗口名称atom_window = "Drawing 1: Atom"rook_window = "Drawing 2: Rook"# 创建黑色空图像size = W, W, 3atom_image = np.zeros(size, dtype=np.uint8)rook_image = np.zeros(size, dtype=np.uint8)
我们创建函数来绘制不同的几何形状。例如,为了绘制原子,我们使用 my_ellipse 和 my_filled_circle:
# 1. 绘制简单原子:# -----------------------# 1.a. 创建椭圆my_ellipse(atom_image, 90)my_ellipse(atom_image, 0)my_ellipse(atom_image, 45)my_ellipse(atom_image, -45)# 1.b. 创建圆my_filled_circle(atom_image, (W // 2, W // 2))
为了绘制象棋车,我们采用了 my_line、rectangle 和 my_polygon:
# 2. 画象棋车# ------------------# 2.a. 创建一个凸多边形my_polygon(rook_image)cv.rectangle(rook_image,(0, 7 * W // 8),(W, W),(0, 255, 255),-1,8)# 2.b. 创建线条my_line(rook_image, (0, 15 * W // 16), (W, 15 * W // 16))my_line(rook_image, (W // 4, 7 * W // 8), (W // 4, W))my_line(rook_image, (W // 2, 7 * W // 8), (W // 2, W))my_line(rook_image, (3 * W // 4, 7 * W // 8), (3 * W // 4, W))
让我们看一下这些函数的内部结构:
my_line:
def my_line(img, start, end):thickness = 2line_type = 8cv.line(img,start,end,(0, 0, 0),thickness,line_type)
正如我们所看到的,my_line 只需调用函数 line(),它会执行以下操作:
○ 从起点 start 到终点 end 画一条线
○ 该线显示在图像 img 中
○ 线条颜色由 ( 0, 0, 0 ) 定义,它是对应于黑色的 RGB 值
○ 线厚度设置为 thickness 值(在本例中为 2)
○ 该线为8连通线型(lineType = 8)
my_ellipse:
def my_ellipse(img, angle):thickness = 2line_type = 8cv.ellipse(img,(W // 2, W // 2),(W // 4, W // 16),angle,0,360,(255, 0, 0),thickness,line_type)
从上面的代码中,我们可以看到函数 ellipse() 绘制椭圆:
○ 椭圆显示在图像 img 中
○ 椭圆中心位于点 (w//2, w//2) 中,并包含在一个大小为 (w//4, w//16) 的矩形框中
○ 椭圆旋转了 angle 度
○ 椭圆在 0 到 360 度之间延伸一条弧
○ 图形的颜色将为 ( 255, 0, 0 ),这意味着 BGR 值为蓝色。
○ 椭圆的 thickness 值是 2。
my_filled_circle:
def my_filled_circle(img, center):thickness = -1line_type = 8cv.circle(img,center,W // 32,(0, 0, 255),thickness,line_type)
与 ellipse 函数类似,我们可以观察到 circle 的接收参数:
○ 显示圆的图像(img)
○ 表示圆中心的点 center
○ 圆的半径:w//32
○ 圆的颜色:( 0, 0, 255 ) 在 BGR 中表示红色
○ 由于 thickness = -1,将绘制圆并填充。
my_polygon:
def my_polygon(img):line_type = 8# Create some pointsppt = np.array([[W / 4, 7 * W / 8], [3 * W / 4, 7 * W / 8],[3 * W / 4, 13 * W / 16], [11 * W / 16, 13 * W / 16],[19 * W / 32, 3 * W / 8], [3 * W / 4, 3 * W / 8],[3 * W / 4, W / 8], [26 * W / 40, W / 8],[26 * W / 40, W / 4], [22 * W / 40, W / 4],[22 * W / 40, W / 8], [18 * W / 40, W / 8],[18 * W / 40, W / 4], [14 * W / 40, W / 4],[14 * W / 40, W / 8], [W / 4, W / 8],[W / 4, 3 * W / 8], [13 * W / 32, 3 * W / 8],[5 * W / 16, 13 * W / 16], [W / 4, 13 * W / 16]], np.int32)ppt = ppt.reshape((-1, 1, 2))cv.fillPoly(img, [ppt], (255, 255, 255), line_type)# 仅画线请使用以下方法:# cv.polylines(img, [ppt], True, (255, 0, 255), line_type)
要绘制填充多边形,我们使用函数 fillPoly():
○ 多边形将在 img 上绘制
○ 多边形的顶点是 ppt 中的点集
○ 多边形的颜色由 (255, 255, 255) 定义,这是白色的 BGR 值
rectangle:
# 2.b. 创建矩形cv.rectangle(rook_image,(0, 7 * W // 8),(W, W),(0, 255, 255),-1,8)
最后介绍 rectangle 函数:
○ 矩形将绘制在 rook_image 上
○ 矩形的两个相对顶点由 ( 0, 7*w // 8 ) 和 ( w, w ) 定义
○ 矩形的颜色由 ( 0, 255, 255 ) 给出,这是黄色的 BGR 值
○ 由于厚度值为 -1,因此矩形将被填充。
官方文档:
https://docs.opencv.org/4.5.5/d7/da8/tutorial_table_of_content_imgproc.html




