背景说明
有时候我们在对图像实时处理的时候,需要直观地展示图像的变化过程,这需要借助于OpenCV的GUI特性,通过和图像进行实时交互来实现。在OpenCV-Python中,可以使用滑动条(Trackbar)来交互地调整图像处理的参数来完成该功能,滑动条功能通常用于调整阈值、滤波器参数、颜色范围等。
学习目标
- 学会把滑动条绑如何定到 OpenCV 的窗口
- 掌握函数cv2.creatTrackbar() 和cv2.getTrackbarPos()的用法
使用步骤
- 创建一个窗口,可以使用
cv2.namedWindow()
函数创建一个具有指定名称的窗口。 - 使用
cv2.createTrackbar()
函数创建一个滑动条。 - 使用
cv2.setTrackbarPos()
函数设置滑动条的初始值。 - 使用
cv2.getTrackbarPos()
函数获取滑动条的当前值。 - 在滑动条的回调函数中,可以根据滑动条的当前值进行相应的处理操作。
函数说明
cv2.creatTrackbar() 函数用来创建滑动条,用法如下:
cv2.createTrackbar(trackbarName, windowName, value, count, onChange)
trackbarName
:滑动条的名称。windowName
:包含滑动条的窗口的名称。value
:滑动条的初始值。count
:滑动条的最大值。onChange
:当滑动条的值发生变化时调用的回调函数。
cv2.setTrackbarPos()
函数设置滑动条的初始值。该函数有三个参数:
trackbarName
:滑动条的名称。windowName
:滑动条所在的窗口的名称。pos
:滑动条的初始值。
cv2.getTrackbarPos()
函数用于获取滑动条的当前值,函数的语法如下:
pos = cv2.getTrackbarPos(trackbarName, windowName)
trackbarName
:滑动条的名称。windowName
:包含滑动条的窗口的名称。pos
:滑动条的当前值。
该函数返回滑动条的当前值。通常在滑动条的回调函数中使用该函数来获取滑动条的值,并根据需要进行处理。
创建滑动条及应用
下面是一个示例,展示如何使用滑动条来调整图像的阈值:
import cv2
import numpy as np
def onChange(value):
threshold = cv2.getTrackbarPos("Threshold", "Image")
_, thresholded_img = cv2.threshold(gray_img, threshold, 255, cv2.THRESH_BINARY)
cv2.imshow("Thresholded Image", thresholded_img)
img = cv2.imread("image.jpg")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("Image")
cv2.imshow("Image", img)
cv2.createTrackbar("Threshold", "Image", 0, 255, onChange)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上面的示例代码中,我们首先读取一张图像,并将其转换为灰度图像。然后创建了一个名字为"Image"的窗口,并在窗口中显示原始图像。接下来,我们使用cv2.createTrackbar()
函数创建一个名为"Threshold"的滑动条,并将其最大值设置为255。在每次滑动条的值发生变化时,都会调用onChange()
函数。onChange()
函数中,我们使用cv2.getTrackbarPos()
函数获取滑动条的当前值,然后根据该值对图像进行阈值处理,并在名为"Thresholded Image"的新窗口中显示处理后的图像。最后,使用cv2.waitKey()
等待用户按下任意键关闭窗口。
运行代码后,会显示一张原始图像和一个滑动条。通过移动滑动条,可以调整阈值,并实时看到阈值处理后的图像更新。
获取滑动条的值
下面是一个示例,展示了如何使用cv2.getTrackbarPos()
函数获取滑动条的当前值:
import cv2
def onChange(value):
threshold = cv2.getTrackbarPos("Threshold", "Image")
print("Current threshold value:", threshold)
img = cv2.imread("image.jpg")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("Image")
cv2.imshow("Image", img)
cv2.createTrackbar("Threshold", "Image", 0, 255, onChange)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上面的示例中,我们创建了一个滑动条并设置了一个回调函数onChange()
。在onChange()
函数中,我们使用cv2.getTrackbarPos()
函数获取滑动条的当前值,并打印出来。运行代码后,通过移动滑动条,可以实时看到滑动条的当前值在控制台输出。
创建多个滑动条
现在我们来创建一个简单的程序来使用滑动条改变画板色进行演示。首先我们创建一个窗口来显示显色,默认情况下窗口的开始色黑色,为了便于显示效果,我们设置三个滑动条来分别控制BGR 的色,效果是当我们滑动滚动时窗口的色也会发生相应改变。
提醒:滑动条的另外一个应用就是用作转换换按。默认情况下 OpenCV 本身不带有按钮函数。所以我们使用滑动条来代替按钮。在我们的程序中我们创建一个转换按只有当换按指向 ON 时滑动条的滑动才有用,否否则窗体就是黑色的。
import cv2
import numpy as np
# 创建回调函数
def nothing(x):
pass
#创建一副色图像
img=np.zeros((300,512,3),np.uint8)
cv2.namedWindow('image')
cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)
switch='0:OFF\n1:ON'
cv2.createTrackbar(switch,'image',0,1,nothing)
while(1):
cv2.imshow('image',img)
k=cv2.waitKey(1)&0xFF
if k==27:
break
r=cv2.getTrackbarPos('R','image')
g=cv2.getTrackbarPos('G','image')
b=cv2.getTrackbarPos('B','image')
s=cv2.getTrackbarPos(switch,'image')
if s==0:
img[:]=0
else:
img[:]=[b,g,r]
cv2.destroyAllWindows()
运行结果:
创建画板
功能:可以自选各种颜色的画笔绘画各种图形。
import cv2
import numpy as np
def nothing(x):
pass
#当标按下时变为True
drawing=False
# 如果 mode 为true绘制矩形。按下 'm'变成绘制曲线。
mode=True
ix,iy=-1,-1
#创建回函数
def draw_circle(event,x,y,flags,param):
r=cv2.getTrackbarPos('R','image')
g=cv2.getTrackbarPos('G','image')
b=cv2.getTrackbarPos('B','image')
color=(b,g,r)
global ix,iy,drawing,mode
#当按下左是回始位置坐标
if event==cv2.EVENT_LBUTTONDOWN:
drawing=True
ix,iy=x,y
#当标左按下并移动是绘制图形。 event可以查看移动 flag查看是否按下
elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
if drawing==True:
if mode==True:
cv2.rectangle(img,(ix,iy),(x,y),color,-1)
else:
# 绘制圆圈小圆点在一就成了线 3 代了笔画的粗细
cv2.circle(img,(x,y),3,color,-1)
# 下注掉的代码是始点为圆心点到终点为半径的
# r=int(np.sqrt((x-ix)**2+(y-iy)**2))
# cv2.circle(img,(x,y),r,(0,0,255),-1)
# 当标松开停止绘画。
elif event==cv2.EVENT_LBUTTONUP:
drawing==False
# if mode==True: # cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) # else: # cv2.circle(img,(x,y),5,(0,0,255),-1)
img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.createTrackbar('R','image',0,255,nothing)
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)
cv2.setMouseCallback('image',draw_circle)
while(1):
cv2.imshow('image',img)
k=cv2.waitKey(1)&0xFF
if k==ord('m'):
mode=not mode
elif k==27:
break
运行结果: