绘制图形函数

                             绘制图形函数


先做准备工作:

import cv2
import numpy as np
import matplotlib.pyplot as plt
# 显示函数
def cv_show(name, img):
    cv2.imshow('name', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

再创建一个黑色的图片:

# 创建一个黑色的照片
'''
numpy.zeros(shape, dtype=float, order=’C’)
创建0矩阵  返回给定形状和类型的新数组,用零填充
shape: int或ints序列 ,例如(2 ,3)或 2
dtype: 数组类型,可选,numpy.int8或numpy.float64
order:可选,是否在存储器中以c或fortran连续(按行或列方式)存储多为数组
'''
img = np.zeros((512, 512, 3), np.uint8)
'''
(512, 512, 3):512*512*3的数组的形式 
np.uint8: 8位的数据类型,最大255
全部填充0,所以是黑色
'''

1.画线

# 只需要知道起点和终点
# 画一条宽度为5的蓝线    起点和终点    BGR格式
cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 3)
'''
img:要画线的图片
(0, 0): 线段的起点
(511, 511): 线段的终点
(255, 0, 0): BGR格式的 要画的线是蓝色的
3: 线段的宽度
'''
cv_show('line', img)

输出结果
在这里插入图片描述

2.画矩形

# 画矩形
# 知道左上角顶点和右下角顶点
cv2.rectangle(img, (300, 30), (500, 100), (0, 255, 0), 3)
'''
img: 要画的图片
(300, 0): 左上角的顶点
(500, 100): 右下角的顶点
(0, 255, 0): BGR 绿色
3: 线宽
'''
cv_show('rectangle', img)

输出结果:
在这里插入图片描述

3.画圆

# 画圆
# 知道中心点坐标和半径大小
cv2.circle(img, (400, 60), 30, (0, 0, 255), -1)
'''
img:要画的图片
(400, 60):中心点的坐标
30:圆的半径
(0, 0, 255):BGR 红色
-1: 是实心的, 如果是其他数字就是线宽
'''
cv_show('circle', img)

输出结果:
在这里插入图片描述

4.画椭圆

椭圆
# 中心点坐标,长轴和短轴的长度,逆时针旋转的角度
# 顺时针方向起始的角度和结束角度
cv2.ellipse(img, (200, 200), (100, 50), 45, 90, 360, (0, 255, 0), -1)
'''
img: 要画的图片
(200, 200): 中心点坐标
(100, 50): 长轴和短轴的长度,如果相等,就是一个圆
45:逆时针旋转的角度  45度就是斜左上角,0度就是正的
90:起始的角度,配合结束的角度 ,可以画一些扇形
360 结束的角度,配合起始的角度 ,可以画一些扇形
(0, 255, 0):BGR  绿色
-1: 实心填充
'''
cv_show('ellipse', img)

输出结果:
在这里插入图片描述

5.画多边形

画空心的:

# 画多边形  需要指定每个顶点的坐标 数组的类型必须是int32
# 画一个黄色的具有四个顶点的多边形
'''
创建一个数组
numpy.array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)
object:公开数组接口的任何对象,__array__方法返回数组的对象,或任何(嵌套)序列
dtype:可选  数组的数据类型,默认是序列中对象所需的最小类型
copy: 可选  默认True 则赋值对象,
order: {'K,'A','C','F'}可选   指定阵列的内存布局  C是行  F是列
subok:可选 如果是True,则子类将被传递,否则返回的数组被强制为基类数组(默认)
ndmin:可选 指定结果数组具有的最小维数,
'''
pts = np.array([[100, 50], [20, 130], [70, 120], [80, 110]], np.int32)
'''
[[100, 50], [20, 130], [70, 120], [80, 110]]: 这是一个二维数组
np.int32: 数据类型是32位
'''
'''
不改变元素的值,改变数组的形状
reshape()
'''
pts = pts.reshape((-1, 1, 2))
# 这里reshape 的第一个参数为-1  表明这一维的长度是根据后面的维度计算出来的
'''
polylines(img, pts,isClosed, color,thickness = 1, lineType = LINE_8, shift = 0)
 img:要画的图片
 pts:多边形的曲线的点的集合
 isClosed:True 封闭的
 color:画的颜色
 thickness:线宽
 lineType:线的类型
 shift:坐标点的小数位数
'''
cv2.polylines(img, [pts], True, (0, 255, 0), 3)
'''
 img:要画的图片
 [pts]:要画的多边形的顶点的集合
 True: 表示多边形是否是封闭的
 (0, 255, 0):BGR 绿色
 3:线宽
'''
cv_show('reshape', img)

输出结果:
在这里插入图片描述
实心多边形

# 画填充实心多边形
'''
fillConvexPoly(img, pts, npts, color, lineType=8, shift=0)
img: 要绘制的图片
pts: 指向单个多边形的指针数组  多边形的顶点集合
npts: 多边形的顶点个数
color: 颜色
lineType: 线条的类型
shift: 顶点坐标的小数点位数
'''
cv2.fillConvexPoly(img, pts, (0, 255, 0))
'''
fillPoly(img,ppt,npt,1,Scalar(255,255,255),lineType);
img: 要绘制的图片
ppt: 多边形的顶点集合
npt: 多边形的顶点数目
1: 要绘制的多边形的数量为1
Scalar(255,255,255): 颜色
lineType: 线的类型
没有线宽的参数 默认是实心
'''
# cv2.fillPoly(img, [pts], (200, 0, 200))
cv_show('fillPoly', img)

输出结果:
在这里插入图片描述

6.在图片上添加文字

在图片上添加文字
'''
cvInitFont(font, font_face, hscale, vscale, shear=0, thickness=1, line_type=8 );
font: 字体初始化
font_face: 字体名称标识符  来自于Hershey字体集
        (http://sources.isc.org/utils/misc/hershey-font.txt)
        FONT_HERSHEY_SIMPLEX  正常大小无衬线字体
        FONT_HERSHEY_DUPLEX 正常大小无衬线字体 更复杂
        FONT_HERSHEY_PLAIN 小号无衬线字体
        FONT_HERSHEY_COMPLEX 正常大小有衬线字体
        FONT_HERSHEY_TRIPLEX 正常大小有衬线字体  更复杂
        FONT_HERSHEY_SCRIPT_SIMPLEX 手写风格字体
        FONT_HERSHEY_SCRIPT_COMPLEX  手写风格字体 更复杂
hscale: 字体宽度, 1.0f 字体的宽度就是最初的字体宽度  0.5f  字体宽度为原来一半
vscale: 字体高度  1.0f 字体的高度就是最初的字体高度  0.5f  字体高度为原来一半
shear:  字体斜度  0  字体不倾斜   1.0f  倾斜45度
thickness: 字体笔划的粗细程度
line_type: 字体笔划的类型
'''
font1 = cv2.FONT_HERSHEY_SIMPLEX
font2 = cv2.FONT_HERSHEY_DUPLEX
font3 = cv2.FONT_HERSHEY_PLAIN
font4 = cv2.FONT_HERSHEY_COMPLEX
font5 = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX
font6 = cv2.FONT_HERSHEY_DUPLEX
font7 = cv2.FONT_HERSHEY_SCRIPT_COMPLEX
'''
 PutText(img, text, org, font, color );
 img:绘制的图片
 text:显示的字符串
 org:第一个字符左下角的坐标
 font:字体结构初始化
 color:文本的字体颜色
'''
cv2.putText(img, 'luatao', (50, 100), font1, 4, (255, 0, 255), 2)
#           图像  绘制的文字   绘制的位置  字体 字体大小  颜色       线宽
cv2.putText(img, 'luatao', (50, 200), font2, 4, (255, 0, 255), 2)
cv2.putText(img, 'luatao', (50, 300), font3, 4, (255, 0, 255), 2)
cv2.putText(img, 'luatao', (50, 400), font4, 4, (255, 0, 255), 2)
cv2.putText(img, 'luatao', (50, 500), font6, 4, (255, 0, 255), 2)
cv_show('text', img)

输出结果:
在这里插入图片描述

7.把鼠标当画笔

查看所有支持的鼠标事件
events = [i for i in dir(cv2) if 'EVENT' in i]
for e in events:
    print(e)
'''
鼠标回调函数固定格式
def draw_circle(event, x, y, flags, param):
event: 鼠标的各种操作
    EVENT_MOUSEMOVE          滑动
    EVENT_LBUTTONDOWN        左键点击
    EVENT_RBUTTONDOWN        右键点击
    EVENT_MBUTTONDOWN        中键点击
    EVENT_LBUTTONUP          左键放开
    EVENT_RBUTTONUP          右键放开
    EVENT_MBUTTONUP          中键放开
    EVENT_LBUTTONDBLCLK      左键双击
    EVENT_RBUTTONDBLCLK      右键双击
    EVENT_MBUTTONDBLCLK      中键双击
x: 窗口的x,y坐标位置
y: 窗口的x,y坐标位置
flags: 鼠标的拖拽时间,以及键盘鼠标联合事件, 共32种事件
    EVENT_FLAG_LBUTTON       左鍵拖曳
    EVENT_FLAG_RBUTTON       右鍵拖曳
    EVENT_FLAG_MBUTTON       中鍵拖曳
    EVENT_FLAG_CTRLKEY       (8~15)按Ctrl不放事件
    EVENT_FLAG_SHIFTKEY      (16~31)按Shift不放事件
    EVENT_FLAG_ALTKEY        (32~39)按Alt不放事件
param:标记了响应事件的函数,自定义了ID
'''
# 鼠标回调函数
# 在图片上双击过的位置绘制一个圆圈。
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), 50, (255, 0, 0), -1)

# 创建图像与窗口并将窗口与回调函数绑定
img = np.zeros((512, 512, 3), np.uint8)
# 新建一个显示窗口
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while True:
    cv2.imshow('image', img)  # 显示图片串口
    if cv2.waitKey(20) & 0xff == 27: # 等待按下esc键
        break
cv2.destroyAllWindows()

输出结果:
在这里插入图片描述

根据选择的模式判断是绘制矩形还是圆形

# 根据选择的模式,在拖动鼠标时绘制矩形或者是圆圈
# 当鼠标按下时变为 True
drawing = False
# 如果mode 为 True 绘制矩形,按下‘m’绘制曲线
mode = True
ix, iy = -1, -1
# 创建回调函数
def draw_circle_Rect(event, x, y, flags, param):
    global ix, iy, drawing, mode  # 调用的是全局变量
    # 当按下左键是返回起始位置坐标
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    # 当鼠标左键按下并移动是绘制图形  event可以查看移动,flag查看是否按下
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
            else:
                # 绘制圆圈  小圆点连在一起就成了线
                cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
    # 当鼠标松开停止绘画
    elif event == cv2.EVENT_LBUTTONUP:
         drawing == False
# 创建窗口并绑定回调函数
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle_Rect)

while True:
    cv2.imshow('image', img)
    k = cv2.waitKey(1) & 0xff  # 等待按键返回ASCII码
    if k == ord('m'):   # 判断ASCII是否等于m
        mode = not mode  # 模式改变
    elif k == 27:
        break

在这里插入图片描述

8.滑动条

# 通过调节滑动条来设定画板颜色

# 回调函数  每次滑动条的滑动都会调用回调函数
def nothing(x):
    pass  # 什么也不做

# 创建一副黑色图像
img = np.zeros((300, 500, 3), np.uint8)
cv2.namedWindow('image')

'''
创建一个滑动控件
createTrackbar(trackbarname, winname, value,count,TrackbarCallback onChange = 0,userdata = 0);
trackbarname: 滑动控件的名字
winname: 滑动控件依附的图像窗口的名字
value: 初始化阈值 滑动条的初始值
count: 滑动控件的刻度范围
TrackbarCallback: 回调函数
# 滑动条的另一个重要应用就是用作转换按钮。
'''
cv2.createTrackbar('R', 'image', 100, 255, nothing)
cv2.createTrackbar('G', 'image', 0, 255, nothing)
cv2.createTrackbar('B', 'image', 0, 255, nothing)

switch = '0:OFF\n1:ON'  # 开关
cv2.createTrackbar(switch, 'image', 0, 1, nothing)
'''
获取滑动条的位置的值
getTrackbarPos(trackbarname,winname)
trackbarname: 控件的名字
winname:窗口的名字
'''
while True:
    cv2.imshow('image', img)  # 显示
    k  = cv2.waitKey(1) & 0xff # 获取ASCII值
    if k == 27:   # 退出键ESC
        break

    r = cv2.getTrackbarPos('R', 'image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')
    s = cv2.getTrackbarPos(switch, 'image')

    if s == 0:  # 如果开关是关的,图片的所有值都是0
        img[:] = 0
    else:
        img[:] = [b, g, r] # 给图片重新赋值 改变颜色
cv2.destroyAllWindows()

输出结果:
在这里插入图片描述这些图片的操作都是基础,接下来就是重点了。要好好学啊。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值