这一部分内容主要包括OpenCV的绘图函数、鼠标回调函数与画图的结合和轨迹栏的使用,绘图函数的传参是关键,鼠标回调函数也是一个相当重要的概念,OpenCV没有提供按钮功能,而轨迹栏可以实现类似的功能,当轨迹栏作为调色板时会有什么样的体验嘞
在这一部分内容中我们会学习使用OpenCV绘制一些不同几何形状的功能函数:cv.line(),cv.circle(),cv.rectangle(),cv.ellipse(),cv.putText(),这些所有的功能函数,都有着相似的传递参数
在开下面的内容之前我们补充一个拓展小知识: np.zerps()的两种用法
在绘制一下常见的几何图形时,我们要从它们本身的特性入手,这些特性与他们的特异参数以及这些参数的来源和意义息息相关
# 创建黑色的图像
img = np.zeros((512,512,3), np.uint8)
# 绘制一条厚度为5的蓝色对角线
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv.circle(img,(447,63), 63, (0,0,255), -1)
# 没错!圆圈是一个封闭的图形,我们在厚度参数的位置传入-1.就可以得到这个用纯色填充的圆圈
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))
# pts.reshape()函数表示自适应该维度大小,如果数组有ROWSx1x2个元素,用reshape()函数返回一个 shape = (ROWS,1,2)的数组
为了获得更好的外观,建议使用lineType = cv.LINE_AA
综合代码实现
import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np
# 创建黑色图像
img = np.zeros((512, 512, 3), np.uint8)
# 1.绘制一条厚度为2的蓝色的线
cv.line(img, (511, 511), (444, 333), (255, 0, 0), 2)
# 2.绘制一个矩形(矩形所需要的参数与直线相似:画布、起始坐标、结束坐标、颜色、厚度)
cv.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)
# 3.绘制一个圆圈(画圆圈有5个参数)
cv.circle(img, (447, 63), 63, (0, 0, 255), -1)
# 4.绘制一个椭圆(画椭圆需要8个参数)
cv.ellipse(img, (256, 256), (100, 50), 60, 0, 90, 255, -1)
# 5.绘制多边形
pts = np.array([[100, 50], [200, 300], [500, 200], [500, 100]], np.int32)
pts = pts.reshape((-1, 1, 2))
cv.polylines(img, [pts], True, (0, 255, 255))
# 6.向图像中添加文本
cv.putText(img, 'Hello OpenCV', (10, 500), font, 2, 255, 2, cv.LINE_AA)
cv.namedWindow('picture')
cv.imshow('picture', img)
cv.waitKey(0)
cv.destroyAllWindows()
这一部分的内容主要呈现了OpenCV图像绘制和OpenCV鼠标事件处理的小结合,关于OpenCV的鼠标事件处理关系到一个很重要的函数:cv.setMouseCallback()
我们主要通过一个小应用程序来学习本部分的内容:双击鼠标绘制一个圆!
首先我们需要创建一个鼠标回调函数,这个函数在发生鼠标双击事件时被触发(鼠标事件可以是与鼠标相关的一切事物),它为我们提供了鼠标的当前位置坐标,提通过这个坐标我们可以做很多操作
创建鼠标回调函数具有特定的格式,该格式在所有地方都相同,它仅在功能上有所不同,现在我们要做的是让这个鼠标回调函数具有双击鼠标绘制一个圆圈的功能
import numpy as np
import cv2 as cv
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):
if event == cv.EVENT_LBUTTONDBLCLK:
cv.circle(img,(x,y),100,(255,0,0),-1)
# 创建一个黑色的图像,一个窗口,并绑定到窗口的功能
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
cv.imshow('image',img)
if cv.waitKey(20) & 0xFF == 27:
break
cv.destroyAllWindows()
更高级的实现
下面我们学习一个关于鼠标回调函数与图形绘制的小高级联动程序:通过拖动鼠标来绘制矩形或圆形(取决于我们选择的模式) ,就像我们在 Paint 应用程序中所做的那样。所以我们的鼠标回调函数有两部分,一部分用于绘制矩形,另一部分用于绘制圆形,键盘键入“ m ”以切换功能
import numpy as np
import cv2 as cv
drawing = False # 如果按下鼠标,则为真
mode = True # 如果为真,绘制矩形。按 m 键可以切换到曲线
ix, iy = -1, -1
# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
elif event == cv.EVENT_MOUSEMOVE:
if drawing:
if mode:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
cv.circle(img, (x, y), 20, (0, 0, 255), -1)
elif event == cv.EVENT_LBUTTONUP:
drawing = False
if mode:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
cv.circle(img, (x, y), 20, (0, 0, 255), -1)
# 创建一个黑色图像,并绑定到窗口的功能
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
while 1:
cv.imshow('image', img)
k = cv.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
if k == 27:
break
cv.destroyAllWindows()
这一部分我们同样通过一个实例来学习,我们实现这样一个功能:有一个显示颜色的窗口,以及三个用于指定B/G/R的跟踪栏,通过滑动轨迹栏来改变窗口的颜色(默认条件下窗口为黑色)
要实现这样一个功能,我们要熟练掌握两个关键函数::cv.getTrackbarPos和cv.createTrackbar
cv.getTrackbarPos()函数详解:这个函数有五个关键参数,第一个参数是轨迹栏名称,第二个参数是它附加到的窗口名称,第三个参数是默认值(初始状态的取值),第四个参数是最大值,第五个参数是执行的回调函数,这个回调函数会每次跟踪栏值的改变并作出相应的反映
我们加入一个方便我们操作的模块:开关。默认情况下OpenCV不具有按钮功能,但是我们可以使用轨迹栏来获得此类功能
代码实现
import numpy as np
import cv2 as cv
def nothing(x):
pass
# 创建一个黑色的图像,一个窗口
img = np.zeros((300,512,3), np.uint8)
cv.namedWindow('image')
# 创建颜色变化的轨迹栏
cv.createTrackbar('R','image',0,255,nothing)
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('B','image',0,255,nothing)
# 为 ON/OFF 功能创建开关
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing)
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == 27:
break
# 得到四条轨迹的当前位置
r = cv.getTrackbarPos('R','image')
g = cv.getTrackbarPos('G','image')
b = cv.getTrackbarPos('B','image')
s = cv.getTrackbarPos(switch,'image')
if s == 0:
img[:] = 0
else:
img[:] = [b,g,r]
cv.destroyAllWindows()
(注:文章内容参考OpenCV4.1中文官方文档)
如果文章对您有所帮助,记得一键三连支持一下哦~