Python OpenCV 绘图

前言

  opencv-python 4.3.2
  官网参考资料

1. 绘图 API

1.1 线段

img	= cv.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
'''
参数:
	ndarray			img					图像
	tuple			pt1					起点
	tuple			pt2					终点
	tuple/list		color				颜色
	int				thickness=1			粗细
	int				lineType=cv.LINE_8	线型
	int				shift=0				Number of fractional bits in the point coordinates.
										点坐标中的小数位数。
注:
	pt1, pt2 可以超出图像的大小范围, 支持负数
	lineType 和 shift 后面单独说明
'''

1.2 lineType、shift 参数说明

(1)lineType

'''
				对应值		含义
cv.FILLED		-1			图形填充
cv.LINE_4		4			4-connected line
cv.LINE_8		8			8-connected line
cv.LINE_AA		16			抗锯齿线
'''

(2)shift

'''
使输入的坐标、半径等都除以 2**shift
小数位数指的是二进制的小数位数, 效果类似右移 shift 位作为当前值
做个简单的测试
'''
import numpy as np
import cv2

img = np.zeros((256,256,3), np.uint8)

for i in range(4):
    cv2.circle(img, (200, 200), 80, (255,255,255), 1, 16, i)
    
cv2.imshow('test', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

1.3 折线 / 多边形

img	= cv.polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]])
'''
参数:
	ndarray		pts			折线 / 多边形各个点的坐标, 输入 shape 为 [1,n,2]
	bool		isClosed	是否闭合, 设为 True 则起点和终点相连
注:
	这里即使设 isClosed=True, 也不能通过 thickness=-1 使图案填充, 会直接报错
'''

# 常用方法
rect = np.array([[[x1,y1], [x2,y2], [x3,y3]]], np.int32)
cv2.polylines(img, rect, False, color, thickness, lineType)

1.4 圆

cv.circle(img, center, radius, color[, thickness[, lineType[, shift]]])
'''
参数:
	tuple		center		圆心坐标 
	int			radius		半径
'''

1.5 椭圆 / 半圆 / 弧线

cv.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]])
'''
参数:
	tuple		center		圆心坐标 
	tuple		axes		(x,y): xy 方向的半轴长
	double		angle		椭圆顺时针旋转角度
	double		startAngle	起点角度 (0为x轴正方向, 顺时针方向为正, 如90为y轴正方向)
	double		endAngle	终点角度 (这里的y轴正方向和平时的xy坐标系不同, 向下为正方向)
'''

1.6 矩形

cv.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
'''
参数:
	tuple		pt1			矩形左上角点 
	tuple		pt2			矩形右下角点
'''

1.7 箭头线

cv.arrowedLine(img, pt1, pt2, color[, thickness[, line_type[, shift[, tipLength]]]])
'''
参数:
	double		tipLength=0.1		箭尖/箭长的比例
'''

1.8 标记

cv.drawMarker(img, position, color[, markerType[, markerSize[, thickness[, line_type]]]])
'''
参数:
	tuple		position		标记坐标
	int			markerType		标记类型
				cv.MARKER_CROSS				+
				cv.MARKER_TILTED_CROSS		×
				cv.MARKER_STAR				+ 和 × 叠加
				cv.MARKER_DIAMOND			◇
				cv.MARKER_SQUARE			□
				cv.MARKER_TRIANGLE_UP		△
				cv.MARKER_TRIANGLE_DOWN		▽
'''

2. 应用示例

2.1 篮球场

import cv2
import numpy as np


def DrawBorder(img, length, width, border, color, line_wide=2, line_type=cv2.LINE_AA):
    cv2.rectangle(img, (border, border), (border+length, border+width), color, line_wide, line_type)

def DrawMidline(img, length, width, border, radius, color, line_wide=2, line_type=cv2.LINE_AA):
    cv2.line(img, (border+length//2, border), (border+length//2, border+width), color, line_wide, line_type)
    cv2.circle(img, (border+length//2, border+width//2), radius, color, line_wide, line_type)
    
def DrawThreepointline(img, length, width, border, border_3pl, radius, color, line_wide=2, line_type=cv2.LINE_AA):
    '''
    border_3pl: 三分线半圆圆心与边线距离
    radius: 三分线半圆半径
    '''
    cv2.ellipse(img, (border+border_3pl, border+width//2), (radius, radius), 0, -90, 90, color, line_wide, line_type)
    cv2.line(img, (border, border+width//2-radius), (border+border_3pl, border+width//2-radius), color, line_wide, line_type)
    cv2.line(img, (border, border+width//2+radius), (border+border_3pl, border+width//2+radius), color, line_wide, line_type)
    
    cv2.ellipse(img, (border+length-border_3pl, border+width//2), (radius, radius),180, -90, 90, color, line_wide, line_type)
    cv2.line(img, (border+length-border_3pl, border+width//2-radius), (border+length, border+width//2-radius), color, line_wide, line_type)
    cv2.line(img, (border+length-border_3pl, border+width//2+radius), (border+length, border+width//2+radius), color, line_wide, line_type)
    
def Draw3szone(img, length, width, border, z_length, z_width, radius, color, zone_type=1, line_wide=2, line_type=cv2.LINE_AA):
    '''
    zone_type: 1矩形、2梯形
    '''
    if zone_type==1:
        cv2.rectangle(img, (border, border+width//2-z_width//2), 
                           (border+z_length, border+width//2+z_width//2), color, line_wide, line_type)
        cv2.ellipse(img, (border+z_length, border+width//2), (radius, radius), 0, -90, 90, color, line_wide, line_type)

        cv2.rectangle(img, (border+length-z_length, border+width//2-z_width//2), 
                           (border+length, border+width//2+z_width//2), color, line_wide, line_type)
        cv2.ellipse(img, (border+length-z_length, border+width//2), (radius, radius), 180, -90, 90, color, line_wide, line_type)
    elif zone_type==2:
        rect = np.array([[[border, border+width//2-z_width//2],
                          [border+z_length, border+width//2-radius],
                          [border+z_length, border+width//2+radius],
                          [border, border+width//2+z_width//2]]], np.int32)
        cv2.polylines(img, rect, False, color, line_wide, line_type)
        cv2.circle(img, (border+z_length, border+width//2), radius, color, line_wide, line_type)
        
        rect = np.array([[[border+length, border+width//2-z_width//2],
                          [border+length-z_length, border+width//2-radius],
                          [border+length-z_length, border+width//2+radius],
                          [border+length, border+width//2+z_width//2]]], np.int32)
        cv2.polylines(img, rect, False, color, line_wide, line_type)
        cv2.circle(img, (border+length-z_length, border+width//2), radius, color, line_wide, line_type)
    

white = (255,255,255)
black = (0,0,0)
blue = (255,0,0)
green = (0,255,0)
red = (0,0,255)

scale = 100
line_color = white
background_color = black

# 球场各参数
border = int(2 * scale)         # 边界
length = int(28 * scale)        # 场地长
width = int(15 * scale)         # 场地宽
radius = int(1.8 * scale)       # 圆圈半径
# 三分线
radius_3pl = int(6.75 * scale)  # 三分线圆圈半径
border_3pl = int(1.57 * scale)  # 三分线圆心与边界距离
# 三秒区
type_3szone = 1                     # 三秒区类型, 1为矩形, 2为梯形
length_3szone = int(5.8 * scale)    # 矩形/梯形长
width_3szone = int(4.9 * scale)     # 矩形/梯形宽

img = (background_color * np.ones((width+border*2, length+border*2, 3))).astype(np.uint8)

DrawBorder(img, length, width, border, line_color)
DrawMidline(img, length, width, border, radius, line_color)
DrawThreepointline(img, length, width, border, border_3pl, radius_3pl, line_color)
Draw3szone(img, length, width, border, length_3szone, width_3szone, radius, line_color, type_3szone)

# 显示
cv2.namedWindow('test', 0)
cv2.resizeWindow('test', int(28*40+2*40), int(15*40+2*40))
cv2.imshow('test', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 存储
# cv2.imwrite("basketball_court_01.jpg", img)

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值