暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OpenCV-Python - 图像处理 - 基础 - 基本绘图

数据库杂货铺 2022-01-30
687

目标

 

在本文中将学习如何:

 

 使用OpenCV函数 line() 画一条线

 

 使用OpenCV函数 ellipse() 绘制椭圆

 

 使用OpenCV函数 rectangle() 绘制一个矩形

 

 使用OpenCV函数 circle() 绘制一个圆

 

 使用OpenCV函数 fillPoly() 绘制填充多边形

 

代码

 

import cv2 as cv
import numpy as np


W = 400


def my_ellipse(img, angle):
thickness = 2
line_type = 8
cv.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 = -1
line_type = 8
cv.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 = 2
line_type = 8
cv.line(img,
start,
end,
(0, 0, 0),
thickness,
line_type)


atom_window = "Drawing 1: Atom"
rook_window = "Drawing 2: Rook"
# 创建黑色空白图像
size = W, W, 3
atom_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, 3
atom_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_linerectangle 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 = 2
line_type = 8
cv.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 = 2
line_type = 8
cv.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 = -1
line_type = 8
cv.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 points
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)

 

要绘制填充多边形,我们使用函数 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


文章转载自数据库杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论