openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并

目录

009:滚动条操作

UI组件-事件相应

代码实现(调整图像亮度)

010:键盘响应机制

键盘响应事件

代码实现 (键盘响应)

011:颜色表操作

查找表LUT(look up table)

代码实现 

 012:通道分离与合并

分离函数

通道合并与混合

通道阈值(二值图像)

代码实现


009:滚动条操作

UI组件-事件相应

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第1张图片

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()

运行结果:

              openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第2张图片

              openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第3张图片

010:键盘响应机制

键盘响应事件

cv.waitKey( [, delay]  ) ->retval

delay如果没有声明或者delay=0,表示一直显示在窗口,按任意键返回。

delay大于0,表示阻塞指定毫秒数。

retval = 27ESC按键

代码实现 (键盘响应)

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)

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第4张图片openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第5张图片

key 2:(ycrcb)                                   key 3:(rgb)

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第6张图片openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第7张图片

011:颜色表操作

查找表LUT(look up table)

1.查表

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第8张图片

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()

运行结果:

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第9张图片openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第10张图片

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第11张图片

 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等参数,又可以把图像变为你所需要的彩色图像。

运行结果:

openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第12张图片openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第13张图片

 012:通道分离与合并

分离函数

cv.split (m[, mv ]) -> mv
m 表示输入图像 , 必须是多通道图像
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()

运行结果:

 openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第14张图片

 openCV-Task03:009-012 滚动条操作;010:键盘响应机制;011:颜色表操作;012:通道分离与合并_第15张图片

你可能感兴趣的:(OpenCV学习,opencv,人工智能,计算机视觉)