使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)

使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头)

这篇博客将介绍使用Python,OpenCV绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头。

1. 效果图

线效果图如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
矩形效果图如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
圆效果图靶子如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)

随机圆心、颜色、半径效果图如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
椭圆效果图如下:

使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
绘制文字效果图如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
绘制多边形轮廓,多边形填充效果图如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
随机颜色,起终点箭头效果图如下:
使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)

2. 原理

2.1 绘制线:cv2.line(canvas, (300, 0), (0, 300), (255, 0, 255), 3)

  • image 画布
  • pt1 起点
  • pt2 终点
  • color 颜色
  • thickness 线的宽度

2.2 绘制矩形:cv2.rectangle(canvas, (200, 50), (225, 125), (0, 0, 255), -1)

  • canvas 要绘制的画布
  • pt1 起始点坐标
  • pt2 终止点坐标
  • color 外轮廓线的颜色
  • thickness 画笔的厚度,负数:填充,整数,轮廓线的宽度

2.3 绘制圆:cv2.circle(canvas, (200, 50), 5, (255, 0, 0), -1)

  • image 画布
  • center 圆心坐标
  • radius 半径
  • color 颜色
  • thickness 正数:线条宽度,负数: 填充区域

2.4 绘制椭圆:cv2.ellipse(canvas, (200, 200), (150, 100), -60, 0, 300, (255, 0, 0), -1)

  • img 图像
  • (int(cX), int(cY)) 中心
  • (150,100) 长轴、短轴
  • angle 旋转角度,负的逆时针旋转,正的顺时针旋转;
  • start_angle 开始角度
  • end_angle 结束角度
  • color 颜色
  • thickness 负数填充,正数线条粗细

2.5 绘制文字:cv2.putText(canvas, “Beautiful”, (30, 100), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 1)

  • img 图片
  • “Good job” 文字内容
  • (int(cX - 10), int(cY)) 绘制起始的像素
  • cv2.FONT_HERSHEY_SIMPLEX
  • 0.45 基于字体特定基大小的比例因子
  • (0, 255, 0) 颜色
  • 2 绘制文本的线条粗细

2.6 NumPy的随机数功能:np.random.randint

随机生成1个数(5,200之间):radius = np.random.randint(5, high=200)
随机生成3个数(0,256之间)color = np.random.randint(0, high=256, size=(3,)).tolist()

3. 源码

# 绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头
# USAGE
# python basic_drawing.py

# 导入必要的包
import numpy as np
import cv2

# 初始化空数组图像并绘制
# 初始化画布(300*300)的3通道
canvas = np.zeros((300, 300, 3), dtype="uint8")
# 绘制文字
# - img 图片
# - "Good job" 文字内容
# - (int(cX - 10), int(cY)) 绘制起始的像素
# - cv2.FONT_HERSHEY_SIMPLEX
# - 0.45 基于字体特定基大小的比例因子
# - (0, 255, 0) 颜色
# - 2 绘制文本的线条粗细
cv2.putText(canvas, "Beautiful", (30, 100), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 1)
cv2.putText(canvas, "Excellent", (50, 150), cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 0, 0), 2)
cv2.putText(canvas, "Good job", (150, 200), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 5)
cv2.putText(canvas, "Marvelously", (20, 250), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 255, 255), 3)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 初始化空数组图像并绘制
# 初始化画布(300*300)的3通道
canvas = np.zeros((300, 300, 3), dtype="uint8")

# 从左上到右下绘制一条绿色的线
green = (0, 255, 0)
cv2.line(canvas, (0, 0), (300, 300), green)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 从右上到左下绘制一条宽度为3像素的红色线
red = (0, 0, 255)
# 绘制线
# --image 画布
# --pt1 起点
# --pt2 终点
# --color 颜色
# --thickness 线的宽度
cv2.line(canvas, (300, 0), (0, 300), red, 3)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

cv2.line(canvas, (50, 100), (300, 250), (0, 255, 255), 2, cv2.LINE_8, 3)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 绘制一个50*50的绿色矩形(从(10,10)到(60*60)
canvas = np.zeros((300, 300, 3), dtype="uint8")
cv2.rectangle(canvas, (10, 10), (60, 60), green)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 绘制另一个宽度为像素的红色矩形,从(50,200)到(200,225)
cv2.rectangle(canvas, (50, 200), (200, 225), red, 5)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 绘制一个蓝色填充的矩形
blue = (255, 0, 0)
# --canvas 要绘制的画布
# --pt1 起始点坐标
# --pt2 终止点坐标
# --color 外轮廓线的颜色
# --thickness 画笔的厚度,负数:填充,整数,轮廓线的宽度
cv2.rectangle(canvas, (200, 50), (225, 125), blue, -1)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 重新初始化一块画布,计算画布的中心
canvas = np.zeros((300, 300, 3), dtype="uint8")
print(canvas.shape[1] / 2, canvas.shape[0] / 2)
print(canvas.shape[1] // 2, canvas.shape[0] // 2)
print((int)(canvas.shape[1] / 2), (int)(canvas.shape[0] / 2))
(centerX, centerY) = (canvas.shape[1] // 2, canvas.shape[0] // 2)
white = (255, 255, 255)

# 遍历不同的圆半径,绘制多个圆
for r in range(0, 175, 25):
    # 绘制白色圆
    cv2.circle(canvas, (centerX, centerY), r, white)
# 展示画布最终效果
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 重新初始化一块画布
canvas = np.zeros((300, 300, 3), dtype="uint8")
# 随机绘制25个圆
for i in range(0, 25):
    # 随机生成5~200的半径
    # 随机生成颜色
    # 随机取一个点作为圆心
    radius = np.random.randint(5, high=200)
    color = np.random.randint(0, high=256, size=(3,)).tolist()
    pt = np.random.randint(0, high=300, size=(2,))

    # 绘制圆在画布上,用填充色
    # --image 画布
    # --center 圆心坐标
    # --radius 半径
    # --color 颜色
    # --thickness 正数:线条宽度,负数: 填充区域
    cv2.circle(canvas, tuple(pt), radius, color, -1)

# 展示杰作到屏幕
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 重新初始化一块画布
canvas = np.zeros((400, 400, 3), dtype="uint8")
# 绘制椭圆
# - img 图像
# - (int(cX), int(cY)) 中心
# - (150,100) 长轴,短轴
# - angle 旋转角度,负的逆时针旋转,正的顺时针旋转;
# - start_angle 开始角度
# - end_angle 结束角度
# - (90,90,90) 颜色
# - -1 负数:填充,正数:线条粗细
cv2.ellipse(canvas, (250, 200), (150, 100), -60, 0, 300, (233, 0, 233), -1)
cv2.ellipse(canvas, (100, 100), (80, 40), 0, 0, 280, (255, 255, 0), 2)
cv2.ellipse(canvas, (80, 300), (60, 30), 90, 30, 360, (0, 255, 255), 4)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)

# 重新初始化一块画布
canvas = np.zeros((400, 400, 3), dtype="uint8")
pts = np.random.randint(50, 300, size=((8, 2)))
print(pts.shape)
print(pts)
# 绘制多边形的轮廓
cv2.polylines(canvas, [pts], isClosed=True, color=(255, 0, 255), thickness=1)
cv2.imshow("polylines", canvas)
cv2.waitKey(0)

# 绘制多边形填充
cv2.fillPoly(canvas, [pts], color=(255, 255, 0))
cv2.imshow("fillPoly", canvas)
cv2.waitKey(0)

# 重新初始化一块画布
canvas = np.zeros((400, 400, 3), dtype="uint8")
# 绘制箭头
cv2.arrowedLine(canvas, (300, 100), (250, 300), (0, 233, 220), 3)
for i in range(6):
    color = np.random.randint(0, high=256, size=(3,)).tolist()
    pt = np.random.randint(0, high=300, size=(2,))
    pt2 = np.random.randint(0, high=300, size=(2,))
    cv2.arrowedLine(canvas, tuple(pt), tuple(pt2), color, 3)

cv2.imshow("arrowedLine", canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()

参考

上一篇:剑指Offer——搜狐畅游笔试题+知识点总结


下一篇:【第二节】PyQt5基本功能