目录
009:滚动条操作
UI组件-事件相应
代码实现(调整图像亮度)
010:键盘响应机制
键盘响应事件
代码实现 (键盘响应)
011:颜色表操作
查找表LUT(look up table)
代码实现
012:通道分离与合并
分离函数
通道合并与混合
通道阈值(二值图像)
代码实现
009:滚动条操作
UI组件-事件相应
1.使用trackbar_callback函数来完成事件响应函数的声明与实现
def trackbar_callback (pos):
print(pos)// 控制台输出或要实现的内容
2.创建窗口函数
cv.namedWindow(winname [, flags]) -> None参数 : winname 表示窗口标题参数 flags 支持的 flag 有:WINDOW_NORMAL – 可以调整窗口大小WINDOW_AUTOSIZE – 根据图像大小自动适应,不可调WINDOW_KEEPRATIO – 可以保持比例窗口,可以调整大小代码实现(调整图像亮度)
实现过程:
• 动态调整,基于滚动条修改常量值,实现动态修改图像亮度并刷新显示• 创建图像窗口• 创建滚动条组件• 在窗口显示图像• 拖拉滚动条修改图像亮度控制台实现功能:def trackbar_callback(pos): print(f"现在的亮度是{pos}"
滚动条实现:
def trackbar_demo(): # 滚动条 image = cv.imread('.\\data\\lena.jpg') cv.namedWindow("trackbar_demo",cv.WINDOW_AUTOSIZE) # 创建一个窗口,名字叫trackbar_demo,WINDOW_KEEPRATIO可以保持比例 cv.createTrackbar("lightness","trackbar_demo",0,200,trackbar_callback) # 将滚动条lightness贴到track_demo窗口上去,滚动条的范围为0-200 cv.imshow("trackbar_demo",image) while True: pos = cv.getTrackbarPos("lightness","trackbar_demo") # 获取滚动条的位置 image2 = np.zeros_like(image) image2[:, :] = (np.uint8(pos),np.uint8(pos),np.uint8(pos)) # 提升亮度 result = cv.add(image, image2) # 降低亮度 # result = cv.subtract(image,image2) cv.imshow("trackbar_demo", result) c = cv.waitKey(1) # 等待图像显示的时间 if c == 27: # 27在ASCLL码值里面代表的是ESC,当输入ESC时,退出循环,程序结束。 break cv.waitKey(1) cv.destroyAllWindows()
运行结果:
010:键盘响应机制
键盘响应事件
cv.waitKey( [, delay] ) ->retval
delay如果没有声明或者delay=0,表示一直显示在窗口,按任意键返回。
delay大于0,表示阻塞指定毫秒数。
retval = 27是ESC按键
代码实现 (键盘响应)
按 ESC 推出按 1 显示 HSV 图像按 2 显示 YCrCb按 3 显示 RGB 图像按 0 恢复原图 BGR 显示def keyboard_demo(): # 键盘响应操作 image = cv.imread(".\\data\\girl.jpg") cv.namedWindow("keyboard_demo", cv.WINDOW_AUTOSIZE) cv.imshow("keyboard_demo",image) while True: c = cv.waitKey(10) # 等待10ms后对图像进行响应操作 # ESC if c == 27: break # key 0 elif c == 48: cv.imshow("keyboard_demo", image) # key 1 elif c == 49: hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV) cv.imshow("keyboard_demo", hsv) # key 2 elif c == 50: ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb) cv.imshow("keyboard_demo",ycrcb) # key 3 elif c == 51: rgb = cv.cvtColor(image,cv.COLOR_BGR2RGB) cv.imshow("keyboard_demo",rgb) cv.waitKey(1) cv.destroyAllWindows()
运行结果:
原图: key 1:(HSV)
key 2:(ycrcb) key 3:(rgb)
011:颜色表操作
查找表LUT(look up table)
1.查表
2.Gamma校正
(1)像素值取值范围在 0~255 之间,每一个值对应一个输出值,这样映射关系,可以先建立查找表 LUT(2)根据输入得像素值作为 index ,在 LUT 中直接映射读取得到 gamma 校正之后得值对 256x256 大小的图像,计算量对比:不应用找表计算 gamma - 65536 次;应用查找表计算 gamma – 256 次代码实现
1.查表
def lut_demo(): cv.namedWindow("lut_demo",cv.WINDOW_NORMAL) lut = [[255,0,255],[125,0,0],[127,255,200],[200,127,127],[0,255,255]] m1 = np.array([[2,1,3,0],[2,2,1,1],[3,3,4,4],[4,4,1,1]]) m2 = np.zeros((4,4,3),dtype=np.uint8) for i in range(4): for j in range(4): index = m1[i,j] m2[i,j] = lut[index] cv.imshow("lut_demo", m2) cv.waitKey(0) cv.destroyAllWindows() # 建立查找表 lut2 = np.zeros((256),dtype=np.uint8) gamma = 0.7 # 一般取0.5-1之间 for i in range(256): print(i,"--",np.log(i/255.0)) lut2[i] = int(np.exp(np.log(i/255.0)*gamma)*255.0) print(lut2) image = cv.imread(".\\data\\girl.jpg") cv.imshow("input",image) cv.namedWindow("girl-gamma",cv.WINDOW_AUTOSIZE) h,w,c = image.shape for row in range(h): for col in range(w): b,g,r = image[row,col] image[row,col] = (lut2[b],lut2[g],lut2[r]) cv.imshow("girl-gamma",image) cv.waitKey(0) cv.destroyAllWindows()
运行结果:
2.自定义查表与系统查表
代码实现:
# 自定义查表 lut3 = np.zeros((256,1,3)) # 创建一个表,256行,一列,三通道,每一个数的index定义为表 for i in range(256): print(i,"--",np.log(i/255.0)) c = int(np.exp(np.log(i/255.0)*gamma)*255.0) lut3[i,0] = (c,c,c) print(lut3) dst = cv.LUT(image,lut3) cv.imshow("girl-gamma",dst) # 系统查表 dst = cv.applyColorMap(image,cv.COLORMAP_PINK) # COLORMAP_COOL cv.imshow("girl-pink",dst) cv.waitKey(0) cv.destroyAllWindows()
applyColorMap可以设置参数,cv.COLORMAP_COOL,图像看起来更凉快
cv.COLORMAP_JET 热图像
在传入图片时可以传入灰色图像,imread(image,cv.IMREAD_GRAYSCALE),然后用applyColorMap方法的参数COLORMAP_JET等参数,又可以把图像变为你所需要的彩色图像。
运行结果:
012:通道分离与合并
分离函数
cv.split (m[, mv ]) -> mvm 表示输入图像 , 必须是多通道图像mv 表示输出的通道合并与混合
cv.merge(mv[, dst])->dst
mv表示各个通道
cv.mixChannels(src, dst, fromTo)->dst
src表示输入多通道图像
fromTo表示通道索引,是用来随意调整通道顺序,[0,2,1,1,2,0]相当于把B和R通道顺序进行转换
dst表示返回结果
通道阈值(二值图像)
cv.inRange ( src , lowerb , upperb [, dst ]) -> dst其中 src 是输入图像Lowerb 是低值Upperb 是高值dst = ( lowerb < src < upperb )相当于对图像进行mask,只显示指定低值和高值之间的像素代码实现
def channel_splits(): image = cv.imread(".\\data\\butterfly.jpg") cv.namedWindow("butterfly", cv.WINDOW_AUTOSIZE) cv.imshow("butterfly", image) mv = cv.split(image) # 通道分离成B,G,R三通道 b, g, r = mv cv.imshow("B-channel", b) # cv.imshow("G-channel",g) # cv.imshow("R-channel",r) mv[0][:,:] = 0 # B通道赋值为0,然后将G和R通道合并 dst = cv.merge(mv) cv.imshow("merge result", dst) # merge操作是合并图像的通道 dst = np.zeros_like(image) # BGR2RGB cv.mixChannels([image], [dst], fromTo=[0, 2, 1, 1, 2, 0]) # fromTo 是用来随意调整通道顺序,[0,2,1,1,2,0]相当于把B和R通道顺序进行转换 cv.imshow("mix-channels", dst) mask = cv.inRange(image, (43, 46, 100), (128, 200, 200)) # 二值化图像(阈值),只显示在低值和高值之间的像素 # BGR先转成HSV然后inRange会取到比较好的效果 cv.imshow('inRange', mask) cv.waitKey(0) cv.destroyAllWindows()
运行结果: