OpenCV快速入门八:图形与文字绘制

一:相关api

1.画线

line(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)

参数
img: 要绘制线段的图像
pt1: 线段的起点
pt2: 线段的终点
color: 线段的颜色,在C++中通过一个Scalar对象定义。对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色
thickness: 线条的宽度
lineType: 线段的类型。可以取值8, 4, 和CV_AA等, 分别代表8邻接连接线,4邻接连接线和反锯齿连接线。默认值为8邻接。为了获得更好地效果可以选用CV_AA(采用了高斯滤波)。
shift: 坐标点小数点位数

LineTypes {
cv::FILLED = -1,
cv::LINE_4 = 4,
cv::LINE_8 = 8,
cv::LINE_AA = 16
}

示例:

cv2.line(img, (10, 20), (300, 400), (0, 0, 255), 5, 4)#4-带锯齿 -1填充 8-平滑一些 16-非常平滑

2.画矩形

rectangle(Mat& img, Point pt1, Point pt2,const Scalar& color, int thickness = 1, int lineType=8, int shift = 0);

参数
img: 要绘制矩形的图像
pt1: 矩形的起点(左上角)
pt2: 矩形的终点(右下角)
color: 矩形的颜色,在C++中通过一个Scalar对象定义
thickness: 边的宽度,若为负数则填充
lineType: 边的类型
shift: 坐标点小数点位数

示例:

cv2.rectangle(img, (10,10), (100, 100), (0, 0, 255), -1)

3.画圆

cvCircle(Mat& img, CvPoint center, int radius, const Scalar& color, int thickness=1, int lineType=8, int shift=0);

img: 要绘制圆的图像
center: 为画圆的圆心坐标
radius: 为圆的半径
color: 为设定圆的颜色,规则根据B(蓝)G(绿)R(红)
thickness: 如果是正数,表示组成圆的线条的粗细程度。否则,表示圆被填充
line_type: 线条的类型。默认是8
shift: 圆心坐标点和半径值的小数点位数

示例:

cv2.circle(img, (320, 240), 5, (0, 0, 255), -1)

4.画椭圆

ellipse(Mat& img, centerCoordinates, axesLength, angle, startAngle, endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0);

img: 要绘制椭圆的图像
centerCoordinates: 它是椭圆的中心坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)
axesLength: 它包含两个变量的元组,分别包含椭圆的长轴和短轴(长轴长度,短轴长度)
angle: 椭圆旋转角度,以度为单位。 按顺时针计算
startAngle: 椭圆弧的起始角度,以度为单位。 注意0度是从左侧开始的
endAngle: 椭圆弧的终止角度,以度为单位 。 注意0度是从左侧开始的
color: 为设定椭圆的颜色,对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色。
thickness: 如果是正数,表示组成椭圆的线条的粗细程度。否则,表示圆被填充
lineType: 线条的类型。默认是8
shift: 它表示中心坐标中的小数位数和轴的小数点位数
椭圆

示例:

cv2.ellipse(img, (320, 240), (100, 50), 15, 0, 360, (0, 0, 255), -1)

5.画多边形

polylines(Mat& img,pts,isClosed=Flase,color,thickness=None,lineType=None,shift=None)

img: 要绘制椭圆的图像
pts: 是一个点对数组,维度为顶点个数n*2,坐标点必须都是int,可以同时画多个独立的多边形,一个或多个多边形的坐标点放在 一个或多个numpy的数组中,而这个数组需要放入一维list中,但即使只有一个numpy的坐标点数组也必须有一个list框
isClosed: 是布尔型,True表示的是线段闭合,False表示的是填充
color: 为设定椭圆的颜色,对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色
thickness: 如果是正数,表示组成多边形的线条的粗细程度。否则,表示圆被填充
lineType: 线条的类型。默认是8
shift: 它表示中心坐标中的小数位数和轴的小数点位数

示例:

pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
#将Ture去掉即为填充多边形
cv2.polylines(img, [pts], True, (0, 0, 255))

6.文字绘制

putText(Mat& img, text, org, font, fontScale,const Scalar& color, int thickness=1, int lineType=8, bottomLeftOrigin);

image: 要绘制文本的图像
text: 要绘制的文本字符串
org: 图像中文本左下角的坐标。坐标表示为两个值的元组,即(X坐标,Y坐标)
font: 字体类型。一些字体类型是FONT_HERSHEY_SIMPLEX,FONT_HERSHEY_PLAIN等
fontScale: 字体比例因子乘以font-specific基本大小
color: 绘制的文本字符串的颜色
thickness: 字体粗细
lineType: 要使用的线的类型
bottomLeftOrigin: 如果为true,则图像数据原点位于左下角。否则,它位于左上角
示例:

cv2.putText(img, "Hello World!", (10, 400), cv2.FONT_HERSHEY_TRIPLEX, 3, (255,0,0))

完整代码

import cv2
import numpy as np
#(y,x)
img = np.zeros((480, 640, 3), np.uint8)

#画线,坐标点为(x, y)
cv2.line(img, (10, 20), (300, 400), (0, 0, 255), 5, 4)#4-带锯齿 -1填充 8-平滑一些 16-非常平滑
cv2.line(img, (80, 100), (380, 480), (0, 0, 255), 5, 16)

#画矩形
cv2.rectangle(img, (10,10), (100, 100), (0, 0, 255), -1)

#画圆
#cv2.circle(img, (320, 240), 100, (0, 0, 255))
cv2.circle(img, (320, 240), 5, (0, 0, 255), -1)

#画椭圆
#度是按顺时针计算的
#0度是从左侧开始的
cv2.ellipse(img, (320, 240), (100, 50), 15, 0, 360, (0, 0, 255), -1)

#画多边形
pts = np.array([(300, 10), (150, 100), (450, 100)], np.int32)
cv2.polylines(img, [pts], True, (0, 0, 255))

#填充多边形
#cv2.fillPoly(img, [pts], (255, 255, 0))

#绘制广本
cv2.putText(img, "Hello World!", (10, 400), cv2.FONT_HERSHEY_TRIPLEX, 3, (255,0,0))

cv2.imshow('draw', img)
cv2.waitKey(0)

二:融合

现在我们已经学到了快速入门八了,也学会了不少api的使用方法,我们尝试着把它融合到一起,来写一个简单的画图代码,实现功能如下:

# 可以通过鼠标进行基本图形的绘制
# 1. 可以画线: 当用户按下l键,即选择了画线。此时,滑动鼠标即可画线。
# 2. 可以画矩形:当用户按下r键,即可选择画矩形。此时,滑动鼠标即可画矩形。
# 3. 可以画圆:当用户按下c键,即可选择画圆。此时,滑动鼠标即可画圆。
# ....

你可以先自己尝试写一下,再看后面我给的代码,加油!!!

import cv2
import numpy as np

#全局变量用于确定要画什么图形    0-drawline, 1-drawrectangle, 2-drawcircle
curshape = 0
#初始坐标
startpos = (0, 0)

# 显示窗口和全黑画布
img = np.zeros((480, 640, 3), np.uint8)


# 鼠标回调函数
def mouse_callback(event, x, y, flags, userdata):
    # print(event, x, y, flags, userdata)
    global curshape, startpos#变量声明

    if (event & cv2.EVENT_LBUTTONDOWN == cv2.EVENT_LBUTTONDOWN):#左键摁下
        startpos = (x, y)#获取起始坐标
    elif (event & cv2.EVENT_LBUTTONUP == cv2.EVENT_LBUTTONUP):#左键松开
        if curshape == 0:  # 线
            cv2.line(img, startpos, (x, y), (0, 0, 255))
        elif curshape == 1:  # 矩形
            cv2.rectangle(img, startpos, (x, y), (0, 0, 255))
        elif curshape == 2:  # 圆
            a = (x - startpos[0])
            b = (y - startpos[1])
            r = int((a ** 2 + b ** 2) ** 0.5)#勾股定理
            cv2.circle(img, startpos, r, (0, 0, 255))
        else:
            print('error:no shape define')


# 创建窗口
cv2.namedWindow('drawshape', cv2.WINDOW_NORMAL)

# 设置鼠标回调
cv2.setMouseCallback('drawshape', mouse_callback)

while True:
    cv2.imshow('drawshape', img)
    key = cv2.waitKey(10) & 0xFF
    if key == ord('q'):
        break
    elif key == ord('l'):  # line
        curshape = 0
    elif key == ord('r'):  # rectangle
        curshape = 1
    elif key == ord('c'):  # circle
        curshape = 2

cv2.destroyAllWindows()

给你们瞅瞅我的“大作”
大作

每日“大饼”:
愿每个人都有一段默默付出 但没有回报的日子 我们把它称之为扎根

猜你喜欢

转载自blog.csdn.net/weixin_52051554/article/details/126160566
今日推荐