opencv提供了绘制直线、矩形、圆、椭圆等多种图形,以及添加文字操作,同时也提供了针对鼠标的单击、双击、滑动、拖曳等常见鼠标操作识别。另外它还可以利用滚动条实现交互功能。
一:绘图基础
在绘图的函数中有一些共有的参数,主要用于设置源图像,颜色,线条属性等。
img:绘制图形的载体
color:颜色,通常BGR格式,如:(0,255,0)表示绿色,对于灰度图,则只能传入灰度值
thickness:线宽,默认1,若设置为-1,则表示填充图像
lineType:线条类型,默认8连接类型。(一般默认就好,有兴趣的自己去了解)
shift:数据精度,一般默认就好。
1、绘制直线
img=cv2.line(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
pt1:线段起点
pt2:线段终点
#####如下所示############
import cv2
import numpy as np
img=np.zeros((400,400,3),np.uint8)
img=cv2.line(img, (20,40), (260,320), (0,250,0), 3, cv2.LINE_AA)
img=cv2.line(img, (0,300), (200,200), (0,250,255), 3, cv2.LINE_8)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
2、绘制矩形
cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
pt1:矩形左上角顶点
pt2:矩形右下角顶点
###########如下所示###########
import cv2
import numpy as np
img=np.ones((400,400,3),np.uint8)
cv2.rectangle(img, (50,20), (300,320), (255,0,0), thickness=-1)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
3、绘制圆
img=cv2.circle(img, center, radius, color, thickness=None, lineType=None, shift=None)
center:圆心
radius:半径
##############如下所示#############
import cv2
import numpy as np
img=np.zeros((400,400,3),np.uint8)
(centerx,centery)=(round(img.shape[1]/2),round(img.shape[0]/2))
for r in range(10,round(img.shape[0]/2),10) :
color=np.random.randint(0,256,size=3).tolist()
cv2.circle(img, (centerx,centery), r, color, 3)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
##################实心############
import cv2
import numpy as np
img=np.ones((400,400,3),np.uint8)*255
for r in range(100) :
centerx=np.random.randint(0,img.shape[1])
centery = np.random.randint(0, img.shape[0])
r=np.random.randint(5,img.shape[0]/5)
color=np.random.randint(0,256,size=3).tolist()#不包含上限high
cv2.circle(img, (centerx,centery), r, color, -1)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
4、绘制椭圆
img=cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness=None, lineType=None, shift=None)
center:椭圆圆心位置
axes:轴长度
angle:偏转角度
startAngle:圆弧起始角角度
endAngle:圆弧终结角角度(官网有较详细说明)
#############如下所示###############
import cv2
import numpy as np
img=np.zeros((400,400,3),np.uint8)
center=(round(img.shape[1]/2),round(img.shape[0]/2))
size=(100,200)
for i in range(0,10):
angle=np.random.randint(0,361)
color=np.random.randint(0,256,3).tolist()
thick=np.random.randint(1,9)
img=cv2.ellipse(img, center, size, angle, 0, 360, color, thick)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
5、绘制多边形
img=cv2.polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
pts:多边形的各个顶点。该数据类型必须为np.int32,不写明的话它会自动默认。
isClosed:是否闭合,若为True,则闭合多边形,否则只是首尾连接成曲线
###################如下所示#############
import cv2
import numpy as np
img=np.ones((400,400,3),np.uint8)*255
pts=np.array([[50,80],[100,350],[69,240],[370,200],[300,150]])
img=cv2.polylines(img, [pts], True, (0,0,255), 3)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
6、在图形上绘制文字
img=cv2.putText(img, text, org, fontFace, fontScale, color, thickness=None, lineType=None, bottomLeftOrigin=None)
text:要绘制的文字(目前不支持汉语)
org:绘制的位置,以文字的左下角为起点
fontFace:字体类型。下面列出4种,想了解更多的可查阅相关资料
cv2.FONT_HERSHEY_SIMPLEX:正常大小的sans-serif字体
cv2.FONT_HERSHEY_COMPLEX:正常大小的serif字体
cv2.FONT_HERSHEY_SCRIPT_SIMPLEX:手写风格字体
cv2.FONT_ITALIC:斜体标记
fontScale:字体大小
bottomLeftOrigin:控制文字的方向,默认为False,当为True时,文字是垂直镜像的。
####################如下所示###############
import cv2
import numpy as np
img=np.zeros((600,600,3),np.uint8)
font1=cv2.FONT_ITALIC
cv2.putText(img,"Hello",(200,200),font1,3,(0,255,0),15)
cv2.putText(img,"Hello",(200,200),font1,3,(255,255,0),5)
font2=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX
cv2.putText(img,"thank",(200,350),font2,3,(0,255,255),5)
cv2.putText(img,"thank",(200,400),font2,3,(0,255,255),5,bottomLeftOrigin=True)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()
二、鼠标交互
1、当用户触发鼠标事件时,我们希望对该事件作出响应。如用户单击鼠标,我们就画一个圆。通常的做法是:创建一个OnMouseAction()响应函数,将要实现的操作写在该响应函数内。响应函数是按照固定的格式创建的。其格式如下:
def OnMouseAction(event,x,y,flage,param):
event:触发了何种事件,具体事件如下event
x,y:代表触发鼠标事件时,鼠标在窗口的位置坐标(x,y)
flage:代表鼠标的拖曳事件,以及触发鼠标联合事件,如下flage
param:函数ID,标识所响应的事件函数,相当于自定义一个OnMouseAction()函数的ID。
OnMouseAction:响应函数的名称,可自定义。
event:
cv2.EVENT_MOUSEMOVE:滑动
cv2.EVENT_LBUTTONDOWN:左键点击
cv2.EVENT_RBUTTONDOWN:右键点击
cv2.EVENT_MBUTTONDOWN:中键点击
cv2.EVENT_LBUTTONUP:左键放开
cv2.EVENT_RBUTTONUP:右键放开
cv2.EVENT_MBUTTONUP :中键放开
cv2.EVENT_LBUTTONDBLCLK :左键双击
cv2.EVENT_RBUTTONDBLCLK:右键双击
cv2.EVENT_MBUTTONDBLCLK :中键双击
cv2.cv2.EVENT_MOUSEHWHEEL:滚动滑轮(正负分别表示左右)
cv2.EVENT_MOUSEWHEEL:滚动滑轮(正负分别表示前后)
flags:
cv2.EVENT_FLAG_LBUTTON : 左鍵拖曳
cv2.EVENT_FLAG_RBUTTON : 右鍵拖曳
cv2.EVENT_FLAG_MBUTTON : 中鍵拖曳
cv2.EVENT_FLAG_CTRLKEY :按Ctrl不放事件
cv2.EVENT_FLAG_SHIFTKEY :按Shift不放事件
cv2.EVENT_FLAG_ALTKEY :按Alt不放事件
定义响应函数后,要将该函数与特定的窗口建立联系,让窗口内的鼠标触发事件时,能够找到该响应函数并执行。要将函数与窗口绑定,可以通过一下函数实现:
cv2.setMouseCallback(winname,onMouse)
winname:绑定的窗口名
onMouse:绑定的响应函数名
import cv2
import numpy as np
d=400
def draw(event,x,y,flages,param):
if event==cv2.EVENT_LBUTTONDOWN:#单击鼠标左键
plx=x
ply=y
p2x=np.random.randint(1,d-50)
p2y=np.random.randint(1,d-50)
color=np.random.randint(0,256,3).tolist()
cv2.rectangle(img,(plx,ply),(p2x,p2y),color,2)#以当前鼠标位置为起点,(p2x,p2y)为终点画矩形
img=np.zeros((d,d,3),np.uint8)
cv2.namedWindow("draw rectangle")#该步骤不能省
cv2.setMouseCallback("draw rectangle",draw)
while(1):
cv2.imshow("draw rectangle",img)
if cv2.waitKey(20)==27:#若在等待期间按下键盘上的"esc"(ascall为27),则退出该窗口
break
cv2.destroyAllWindows()
##############键盘鼠标双重控制##############
import cv2
import numpy as np
thickness=-1
d=400
mode=1
def draw(event,x,y,flages,param):
if event==cv2.EVENT_LBUTTONDOWN:
a=np.random.randint(1,d-50)
r=np.random.randint(1,d/4)
angle=np.random.randint(0,361)
color=np.random.randint(0,256,3).tolist()
if mode==1:
cv2.rectangle(img,(x,y),(a,a),color,thickness)
elif mode ==2:
cv2.circle(img,(x,y),r,color,thickness)
elif mode==3:
cv2.line(img,(a,a),(x,y),color,3)
elif mode==4:
cv2.ellipse(img,(x,y),(50,100),angle,0,360,color,thickness)
elif mode==5:
cv2.putText(img,"hello word !",(0,round(d/2)),cv2.FONT_HERSHEY_SIMPLEX,2,color,5)
img=np.ones((d,d,3),np.uint8)*255
cv2.namedWindow("draw rectangle")#该步骤不能省
cv2.setMouseCallback("draw rectangle",draw)
while(1):
cv2.imshow("draw rectangle",img)
k=cv2.waitKey(1)
if k==ord("r"):#####键盘按下”r“时要记得按回车键,否则键盘控制无效
mode=1
elif k==ord("k"):
mode=2
elif k==ord("e"):
mode=3
elif k==ord("l"):
mode=4
elif k==ord("s"):
mode=5
elif k==27:
break
cv2.destroyAllWindows()
2、滚动条
滚动条(Trackbar)在opencv中是非常方便的交互工具,它依附于特定的窗口而存在,通过调节滚动条能够设置、获取指定范围内的特定值。其定义如下:
cv2.createTrackbar(trackbarName, windowName, value, count, onChange)
trackbarName:滚动条名称
windowName:滚动条依附窗口的名称
value:初始值,该值决定滑动条中滑块的位置
count:滑动条的最大值。通常情况下,其最小值为0.
onChange:回调函数,一般情况下,将滑动条改变后要实现的操作写在回调函数内。
函数cv2.createTrackbar()用于生成滚动条,拖动滚动条,就可以设置滚动条的值,并让其返回对应的值,滚动条的值可以用函数cv2.getTrackbarPos()获取。
retval=cv2.getTrackbarPos(trackbarname, winname)
retval:获取函数cv2.getTrackbarPos()生成的滚动条的值
trackbarname:滚动条的名称
winname:滚动条所依附窗口的名称
##########滚动条实现调色板##################
import cv2
import numpy as np
def changecolor(x):
r=cv2.getTrackbarPos("R","image")
g=cv2.getTrackbarPos("G","image")
b=cv2.getTrackbarPos("B","image")
img[:]=[b,g,r]
img=np.zeros((100,600,3),np.uint8)
cv2.namedWindow("image")
cv2.createTrackbar("R","image",0,255,changecolor)
cv2.createTrackbar("G","image",0,255,changecolor)
cv2.createTrackbar("B","image",0,255,changecolor)
while(1):
cv2.imshow("image",img)
k=cv2.waitKey(1)&0xFF
if k==27:
break
cv2.destroyAllWindows()
#######################滑动条作为选择开关#########
import cv2
import numpy as np
d=400
global thickness
thickness=2
def fill(x):
pass
def draw(event,x,y,flage,param):
if event==cv2.EVENT_LBUTTONDBLCLK:
x1=np.random.randint(1,d-50)
y1=np.random.randint(1,d-50)
color=np.random.randint(0,256,3).tolist()
cv2.rectangle(img,(x,y),(x1,y1),color,thickness)
img=np.ones((d,d,3),np.uint8)*255
cv2.namedWindow("image")
cv2.setMouseCallback("image",draw)
cv2.createTrackbar("R","image",0,1,fill)
while(1):
cv2.imshow("image",img)
k=cv2.waitKey(1)&0xFF
g=cv2.getTrackbarPos("R","image")
if g==0:
thickness=-1
else:
thickness=2
if k==27:
break
cv2.destroyAllWindows()
################滑动条控制阈值处理参数###############
import cv2
def onType(a):
Type = cv2.getTrackbarPos(tType, "image")
Value = cv2.getTrackbarPos(tValue, "image")
ret,dst=cv2.threshold(img,Value,255,Type)#阈值类型可以用数字表示
cv2.imshow("image",dst)
def onValue(a):
Type=cv2.getTrackbarPos(tType,"image")
Value=cv2.getTrackbarPos(tValue,"image")
ret, dst = cv2.threshold(img, Value, 255, Type)
cv2.imshow("image", dst)
img=cv2.resize(cv2.imread("img/5.jpg"),(400,400))
cv2.namedWindow("image")
cv2.imshow("image",img)
tType="Type"
tValue="Value"
cv2.createTrackbar(tType,"image",0,4,onType)
cv2.createTrackbar(tValue,"image",0,255,onValue)
if cv2.waitKey(0)==27:
cv2.destroyAllWindows()