本节主要在上一节基础上进一步来完整实现画图,上一节的重点在于鼠标事件,但在函数的实际运用中并不多,本节也会用到。本节主要想实现以下功能:
1、正常的画图部分,增加可以修改画笔颜色以及粗细,并能够实时预览效果;
2、可以切换画笔模式,用来画矩形,按下'm'键来实现切换;
3、实现橡皮擦功能
实现步骤:
1. 创建画板(画板大小为490×720)#画板大小可随自己喜欢来设置
img=255*np.ones((490,720,3),np.uint8)#创建画板
2. 创建画笔选择的滑动条,以及橡皮擦开关(用滑动条代替),回调函数什么也不做
#创建画图颜色滑动条
cv2.createTrackbar('r','mPaint',0,255,nothing)
cv2.createTrackbar('g','mPaint',0,255,nothing)
cv2.createTrackbar('b','mPaint',0,255,nothing)
#创建画笔粗细
cv2.createTrackbar('thickness','mPaint',1,8,nothing)
#创建一个橡皮擦
switch='erase'
cv2.createTrackbar(switch,'mPaint',0,1,nothing)
3. 设置鼠标回调函数,监视鼠标事件,以作出回应
#创建窗口
cv2.namedWindow('mPaint')
cv2.setMouseCallback('mPaint',draw_circle)
4. 完成回调函数draw_circle
#初始化
ix,iy=0,0#用来存放矩形绘画时的左上角坐标
painting=False#画笔初始化为false,表示此时没有画图
mode=False#存放切换功能
#画图函数
def draw_circle(event,x,y,flags,param):
global ix,iy,mode,painting#可以将画笔信息也用全局变量,从而省去下一行
color,thickness,s=get_painter()#s存放橡皮擦开关状态
#监听鼠标事件,若左键按下则表示画图开始
if event==cv2.EVENT_LBUTTONDOWN:
ix,iy=x,y
painting=True
#如果按着鼠标左键滑动,则开始在鼠标位置画圆,从而连成曲线
elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
if painting:
if s==1:
cv2.circle(img,(x,y),16,(255,255,255),-1)
else:
if mode==False:
cv2.circle(img,(x,y),thickness,color,-1)
else:
#绘制矩形
cv2.rectangle(img,(ix,iy),(x,y),color,-1)
elif event==cv2.EVENT_LBUTTONUP:
painting=False
5. 完成获取画笔信息函数get_painter()
def get_painter():
#获取各个滑动条的数值,来创建画笔颜色
r=cv2.getTrackbarPos('r','mPaint')
g=cv2.getTrackbarPos('g','mPaint')
b=cv2.getTrackbarPos('b','mPaint')
#获取画笔粗细
thickness=cv2.getTrackbarPos('thickness','mPaint')
#获取橡皮擦信息,用s代表
s=cv2.getTrackbarPos(switch,'mPaint')
color=(b,g,r)#openCV的色值(B,G,R)
return color,thickness,s
6. 主循环:重复的显示我们的画图,为了响应速度,在这里我们可以将预览写进去,完成切换mode的取反
#主循环
while(True):
color,thickness,_=get_painter()
draw_line(color,thickness)
cv2.imshow('mPaint',img)
k=cv2.waitKey(10) & 0xFF#延迟时间
if k==ord('m'):
mode=not mode
elif k==ord('q'):
break
7. 完成预览函数(利用画笔信息画直线)
#显示画笔粗细
def draw_line(color,thickness):
cv2.rectangle(img,(680,0),(720,40),(255,255,255),-1)#为画笔预览空出一个空间,否则画笔预览会被淹没
cv2.line(img,(685,20),(716,20),color,thickness+1)
8. 按下'q'时,清除所有的窗口
#清除窗口
cv2.destroyAllWindows()
9. 总结
做这一部分,主要是在教程的基础上加内容,然后调试,修改。与上一节相比,这一节在对鼠标事件的监控添加了一个左键释放的部分,此时将painting改为false,这样做使得代码更有头有尾,即当鼠标左键按下开始创建画笔,按住左键移动实现绘画,松掉左键删除画笔,更加完整。
10. 实际绘画效果: