绘制直线
cv2.line(img, pt1, pt2, color, thickness=1, lineType=LINE_8)
上述代码可以从pt1点绘一条线到pt2点。
img:绘图对象
pt1:线段的起点,画布的左上角坐标是(0, 0)
pt2:线段的终端
color:(B,G,R),所以(255,0,0)是蓝色
thickness:线条宽度,默认是1
lineType:可选参数,指线条样式,有LINE_4、LINE_8和LINE_AA可选,默认是LINE_8
import cv2
import numpy as np
img = np.ones((350,500,3),np.uint8)*255 # 建立白色底的画布
cv2.line(img,(1,1),(300,1),(255,0,0)) # 上方水平直线
cv2.line(img,(300,1),(300,300),(255,0,0)) # 右边垂直直线
cv2.line(img,(300,300),(1,300),(255,0,0)) # 下边水平直线
cv2.line(img,(1,300),(1,1),(255,0,0)) # 左边垂直直线
cv2.imshow("My Draw",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
img = np.ones((350,500,3),np.uint8)*255
img[1:300,1:300] = (0,255,255) # 设定黄色底
cv2.line(img, (1,1), (300,1),(255,0,0))
cv2.line(img,(300,1),(300,300),(255,0,0))
cv2.line(img,(300,300),(1,300),(255,0,0))
cv2.line(img,(1,300),(1,1),(255,0,0))
for x in range(150,300,10):
cv2.line(img,(x,1),(300,x-150),(255,0,0))
for y in range(150,300,10):
cv2.line(img,(1,y),(y-150,300),(255,0,0))
cv2.imshow('My Draw', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制矩形
import cv2
import numpy as np
img = np.ones((350,500,3),np.uint8)*255
cv2.rectangle(img,(1,1),(300,300),(255,0,0)) # 绘制矩形
for x in range(150,300,10):
cv2.line(img,(x,1),(300,x-150),(255,0,0))
for y in range(150,300,10):
cv2.line(img,(1,y),(y-150,300),(255,0,0))
cv2.imshow("My Draw",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.rectangle(img, pt1, pt2, color, thickness=1, lineType=LINE_8)
img:绘图对象
pt1:矩形的左上角坐标,数据格式是元组(x,y)
pt2:矩形的右下角坐标,数据格式是元组(x,y)
color:(B,G,R)方式处理色彩
thickness:线条宽度,默认是1.如果宽度设为-1,则建立实心矩形
lineType:可选参数,指线条样式,有LINE_4、LINE_8和LINE_AA可选,默认是LINE_8
import cv2
import numpy as np
img = np.ones((350,500,3),np.uint8)*255
cv2.rectangle(img,(1,1),(300,300),(0,255,255),-1) # 设定黄色底
cv2.rectangle(img,(1,1),(300,300),(255,0,0)) # 绘制矩形
for x in range(150,300,10):
cv2.line(img,(x,1),(300,x-150),(255,0,0))
for y in range(150,300,10):
cv2.line(img,(1,y),(y-150,300),(255,0,0))
cv2.imshow("My Draw",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制圆形
import cv2
import numpy as np
height = 400
width = 600
img = np.zeros((height,width,3),np.uint8)
for i in range(0,50):
cx = np.random.randint(0,width)
cy = np.random.randint(0,height)
color = np.random.randint(0,256,size=3).tolist() # tolist()函数可以将数组改为列表
r = np.random.randint(5, 100)
cv2.circle(img,(cx,cy),r,color,-1)
cv2.imshow("Random Circle",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.circle(img, center, radius, color, thickness=1, lineType=LINE_ 8 )
center:设定圆中心坐标,数据格式是元组(x,y)
radius:设定半径
color:(B,G,R)
thickness:线条宽度,默认是1,如果宽度设为-1,则建立实心圆形
lineType:可选参数,指线条样式,有LINE_4、LINE_8和LINE_AA可选,默认是LINE_8
绘制椭圆或椭圆弧
cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness=1, lineType=LINE_ 8 )
axes:轴的长度
angle:椭圆偏移的角度
startAngle:圆弧起点的角度
endAngle:圆弧终点的角度
import cv2
import numpy as np
img = cv2.imread('antarctic.jpg')
cy = img.shape[0] // 2 # 中心点y的坐标
cx = img.shape[1] // 2 # 中心点x的坐标
size = (200,120)
for i in range(0,15):
angle = np.random.randint(0,361)
color = np.random.randint(0,256,size=3).tolist()
cv2.ellipse(img,(cx,cy),size,angle,0,360,color,1)
cv2.imshow('My Draw',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
绘制多边形
cv2.polylines(img,pts,isClosed,color,thickness=1,lineType=LINE_8)
pts:Numpy数组,内含多边形顶点的坐标
isClosed:如果是True则建立封闭式多边形,也就是第一个点和最后一个点会连接。如果是False则建立开放式多边形,也就是第一个点和最后一个点不会连接。
import cv2
import numpy as np
img1 = np.ones((200,300,3),np.uint8)*255
pts = np.array([[50,50],[250,50],[200,150],[100,150]])
cv2.polylines(img1,[pts],True,(255,0,0),5)
img2 = np.ones((200,300,3),np.uint8)*255
cv2.polylines(img2,[pts],False,(0,0,255),3)
cv2.imshow('isClosed_Ture',img1)
cv2.imshow('isClosed_False',img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出文字
cv2.putText(img, text,org, fontFace,fontScale,color,thickness=1,lineType=LINE_8,bottomLeftOrigin=False)
text:要输出的文字
org:文字位置,是指第一个文字左下方的坐标(x,y)
fontFace:文字的字体样式,常见字体样式如下
FONT_HERSHEY_SIMPLEX:sans-serif字型,正常大小
FONT_HERSHEY_PLAIN:sans-serif字型,较小字型
FONT_HERSHEY_COMPLEX:sans字型,正常字型
FONT_HERSHEY_TRIPLEX:sans字型,较小字型
FONT_HERSHEY_SCRIPT_SIMPLEX:手写风格的字型
FONT_ITALIC:italic字型(斜体字)
frontScale:文字的字体大小
bottomLeftOrigin:默认是False,当设为True时,可以有垂直倒影的效果。
import cv2
import numpy as np
img = np.ones((300,600,3),np.uint8)*255
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'Python',(150,180),font,3,(255,0,0),12)
cv2.putText(img,"Python",(150,180),font,3,(0,255,255),5)
cv2.imshow("Python",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
中文输出
opencv默认只支持英文,不过可以使用PIL模块,设置成可以输出中文,
1.将opencv的图像格式转换成PIL图像格式
2.使用PIL格式输出中文
3.将PIL的图像格式转换成Opencv图像格式
import cv2
import numpy as np
from PIL import Image,ImageDraw,ImageFont
def cv2_Chinese_Text(img,text,left,top,textColor,fontSize):
if(isinstance(img,np.ndarray)):
img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img)
fontText = ImageFont.truetype(
r"C:\Users\System-Pc\Desktop\simsun.ttc",
fontSize,
encoding="utf-8"
)
draw.text((left,top),text,textColor,font=fontText)
return cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)
img = cv2.imread("antarctic.jpg")
img = cv2_Chinese_Text(img, "我在南极",220,100,(0,0,255),50)
cv2.imshow("Antarctic",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
反弹球的设计
(1)选定位置显示反弹球
(2)让反弹球显示一段时间
(3)在新位置显示反弹球
(4)回到步骤(2)
import time
time.sleep(speed) # 单位是秒
import cv2
import numpy as np
import time
from random import *
width = 640
height = 480
r = 15
speed = 0.01
x = int(width/2)-r
y = 50
y_step = 5
while cv2.waitKey(1) == -1:
if y > height - r or y<r: # 反弹球超出画布下边界或者上边界
y_step = -y_step
y += y_step
img = np.zeros((height,width,3),np.uint8)*255
cv2.circle(img,(x,y),r,(255,0,0),-1)
cv2.imshow("Bouncing Ball",img)
time.sleep(speed)
cv2.destroyAllWindows()
上述反弹球是垂直移动,可以使用y_step设定移动步伐,如果y_step是正值则球往下方移动,如果y_step是负值则球往上移动。
import cv2
import numpy as np
import time
from random import *
width = 640
height = 480
r = 15
speed = 0.01
x = 50
y = 50
random_step = [3,4,5,6,7]
shuffle(random_step)
x_step = random_step[0] # 随机产生x步伐
y_step = 5
while cv2.waitKey(1) == -1:
if x >width -r or x<r:
x_step = -x_step
if y>height-r or y<r:
y_step = -y_step
x+=x_step
y+=y_step
img = np.ones((height,width,3),np.uint8)*255
cv2.circle(img,(x,y),r,(255,0,0),-1)
cv2.imshow("Bouncing Ball",img)
time.sleep(speed)
cv2.destroyAllWindows()
鼠标事件
OnMouseAction(event, x, y, flags, param)
event:鼠标事件名称
EVENT_MOUSEMOVE:0,移动鼠标
EVENT_LBUTTONDOWN:1,单击
EVENT_RBUTTONDOWN:2,右击
EVENT_MBUTTONDOWN:3,单击鼠标中间键
EVENT_LBUTTONUP:4,放开鼠标左键
EVENT_RBUTTONUP:5,放开鼠标右键
EVENT_MBUTTONUP:6,放开鼠标中键
EVENT_LBUTTONBCLK:7,双击
EVENT_RBUTTONBCLK:8,双击鼠标右键
EVENT_MBUTTONBCLK:9,双击鼠标中间键
x,y:鼠标事件发生时,鼠标所在x轴,y轴坐标
flag:代表鼠标拖曳事件,或是键盘与鼠标综合事件
EVENT_FLAG_LBUTTON:1,按住左键拖曳
EVENT_FLAG_RBUTTON:2,按住右键拖曳
EVENT_FLAG_MBUTTON:4,按住中间键拖曳
EVENT_FLAG_CTRLKEY:8~15,按住ctrl键不放
EVENT_FLAG_SHIFTKEY:16~31,按住Shift键不放
EVENT_FLAG_ALTKEY:32~39,按住Alt键不放
param:标记函数ID
import cv2
import numpy as np
def OnMouseAction(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
print(f"在x={x},y={y},单击")
elif event == cv2.EVENT_RBUTTONDOWN:
print(f"在x={x},y={y},右击")
elif event == cv2.EVENT_MBUTTONDOWN:
print(f"在x={x},y={y},单击鼠标中间键")
elif flags == cv2.EVENT_FLAG_LBUTTON:
print(f"在x={x},y={y},按住鼠标左键拖曳")
elif flags == cv2.EVENT_FLAG_RBUTTON:
print(f"在x={x},y={y},按住鼠标右键拖曳")
image = np.ones((200,300,3),np.uint8)*255
cv2.namedWindow('Opencv Mouse Event')
cv2.setMouseCallback("Opencv Mouse Event",OnMouseAction)
cv2.imshow('Opencv Mouse Event',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.setMouseAction('image', OnMouseAction)
image:窗口名称
OnMouseAction:
单击可以在鼠标光标位置建立实心圆,圆半径10~50随机产生,色彩也随即生成。右击可以建立线条宽度为3的随机空心圆,英文模式下,按下Q键可以结束程序。
import cv2
import numpy as np
def OnMouseAction(event, x, y, flag, param):
color = np.random.randint(0,high=256,size=3).tolist()
r = np.random.randint(10,50)
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image, (x,y), r, color,-1)
elif event == cv2.EVENT_RBUTTONDOWN:
cv2.circle(image, (x,y),r,color,3)
height = 400
width = 600
image = np.ones((height,width,3),np.uint8)*255
cv2.namedWindow('Draw Circle')
cv2.setMouseCallback('Draw Circle', OnMouseAction)
while 1:
cv2.imshow('Draw Circle', image)
key = cv2.waitKey(100) # 0.1秒检查一次
if key == ord('Q') or key == ord('q'):
break
cv2.destroyAllWindows()
如果按住键盘S键,再单击可以建立实心圆;如果没有按键盘S键,可以产生空心圆。
如果按住键盘S键,再右击可以建立实心矩形;如果没有按键盘S键,可以产生空心矩形。
在英文输入模式下,按下Q键可以结束程序。
import cv2
import numpy as np
def OnMouseAction(event, x,y,flags,param):
color = np.random.randint(0,high=256,size=3).tolist()
if event == cv2.EVENT_LBUTTONDOWN:
r = np.random.randint(10,50)
if key == ord('s'):
cv2.circle(image, (x,y),r,color,-1)
else:
cv2.circle(image,(x,y),r,color,3)
elif event == cv2.EVENT_RBUTTONDOWN:
px = np.random.randint(10,100)
py = np.random.randint(10,100)
if key == ord('s'):
cv2.rectangle(image,(x,y),(px,py),color,-1)
else:
cv2.rectangle(image,(x,y),(px,py),color,3)
height = 400
width = 600
image = np.ones((height,width,3),np.uint8)*255
cv2.namedWindow("MyDraw")
cv2.setMouseCallback("MyDraw",OnMouseAction)
while 1:
cv2.imshow("MyDraw",image)
key = cv2.waitKey(100)
if key == ord('Q') or key == ord('q'):
break
cv2.destroyAllWindows()
滚动条
cv2.createTrackbar(trackbarname, winname, value, count, onChange)
trackbarname:滚动条的名称
winname:窗口名称
value:滚动条的初值
count:滚动条的最大值
onChange:回调函数,将滚动条所要执行的操作写在此处
程序执行过程中用户可以操作滚动条,OpenCv提供了getTrackbarPos()函数,可以使用它获得滚动条的目前值
code = getTrackbarPos(trackername, winname)
trackername:滚动条名称
winname:窗口名称
import cv2
import numpy as np
def onChange(x):
b = cv2.getTrackbarPos("B",'canvas')
g = cv2.getTrackbarPos("G",'canvas')
r = cv2.getTrackbarPos("R",'canvas')
canvas[:]=[b,g,r]
canvas = np.ones((200,640,3),np.uint8)*255
cv2.namedWindow("canvas")
cv2.createTrackbar("B",'canvas',0,255,onChange)
cv2.createTrackbar("G",'canvas',0,255,onChange)
cv2.createTrackbar("R",'canvas',0,255,onChange)
while 1:
cv2.imshow('canvas',canvas)
key = cv2.waitKey(100)
if key ==27: # 按Esc键结束
break
cv2.destroyAllWindows()
滚动条当作开关
将滚动条当作开关的应用,默认开关是0,这时单击可以绘制空心圆。
单击滚动条轨迹可以将开关设为1,这时单击可以绘制实心圆。按Q键则程序结束。
import cv2
import numpy as np
def onChange(x):
pass
def OnMouseAction(event,x,y,flags,param):
color = np.random.randint(0,high=256,size=3).tolist()
r = np.random.randint(10,50)
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(image,(x,y),r,color,thickness)
thickness = -1
height =400
width = 600
image = np.ones((height,width,3),np.uint8)*255
cv2.namedWindow("Draw Circle")
cv2.setMouseCallback("Draw Circle",OnMouseAction)
cv2.createTrackbar('Thickness','Draw Circle',0,1,onChange)
while 1:
cv2.imshow('Draw Circle',image)
key = cv2.waitKey(100)
num = cv2.getTrackbarPos('Thickness','Draw Circle')
if num == 0:
thickness = -1
else:
thickness = 3
if key == ord('Q') or key == ord('q'):
break
cv2.destroyAllWindows()