Opencv调参神器——trackBar控件

本文介绍了如何使用OpenCV中的trackBar控件进行参数调整,以简化计算机视觉任务中的调参过程。文章通过三个案例,包括图片颜色调整、Canny算子参数调整和图像融合参数调整,详细阐述了trackBar的使用方法,帮助读者快速掌握这一调参神器,提升工作效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

调参需求介绍

想要学好计算机视觉,有一个库必不可少,那就是Opencv,Open即为开放的意思,说明这个库已经开源。cv是Computer Vision,即计算机视觉。Opencv底层是用C++编写的,保证了运行的速度。而Python在C++的基础上编写了调用接口API,这样我们可以使用更为简单的Python语言完成计算机视觉的任务。换句话来说,你只需要会调库,会用给定的函数就能不错的完成任务。
相信你一定听过一个词——调参,即调整参数,使得在该参数下程序达到最佳的效果。所以有人戏谑,只要当好调包侠和调参侠就是学号python-opencv,确实是这样的,“调包侠”好说,只要学会API的输入输出就可以了,但是调参是个非常难的任务。假设一个API有两个参数,每个参数有三种情况,那么就有9种情况,如果有两个API,那就是81种情况。而且在实际工程下,不仅API会很多,而且变化值也很多,很多都是可以连续变化的。
再没学习tarkbar之前,我调参也是一个一个去试,基本流程就是改变某个参数,运行,比较和上一个情况的优劣。常常会出现上个参数调好了,下一个参数的改变也会影响到上个参数。常常是写程序一小时,调参三小时。不知道你是否也会有这种苦恼,这篇文章就通过几个案例详细介绍trackBar控件,大大减少你的调参时间!

trackBar控件介绍

trackBar最大的作用就是将变量值以刻度条的形式呈现出来,在同一个界面中,支持多个刻度条同时变化,最终结果是在所以刻度条的共同作用下形成的。你可以拖动刻度条,给参数附不同的值,这样可以达到再不修改代码的前提下,快速确定最优参数
在这里插入图片描述

上图即为用trackBar控件设置Canny算子参数,对lena图片进行边缘检测。**可以看到上面有三个刻度条,你可以直接拖动刻度条给参数附不同的值,下面的图片实时变化,你可以观察这些参数变化对图片产生的影响,从而快速选择最合适的一组参数。这样的优点就是快速,便捷,且很直观。缺点就是会增加代码量,但是trackbar控件代码写起来也十分简单。 下面我们就通过几个案例具体学习一下trackBar,相信学完之后你会对调参有一个新的理解!

trackBar控件使用函数

trackBar控件在使用时需要两个函数,一个是创建函数,一个是获取值函数。在opencv中,给我们提供了相应的API,我们可以直接调用,非常方便。
创建函数
cv2.createTrackbar(trackbarname,winname,value,count,onChange)

  • 功能:创建TrackBar控件
  • trackbarname:名称
  • winname:显示窗口
  • value为trackbar的默认值
  • count为bar的最大值,最小为0
  • OnChange:回调函数

获取值函数
cv2.getTrackbarPos(trackbarname,winname)

  • 功能获取TrackBar当前值
  • trackbarname:上面创建的trackbar对象名称
  • winname:显示窗口的名称

上面提到一个回调函数,回调函数就是函数指针的调用,即是一个通过函数指针调用的函数;如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就说这是回调函数。如果不理解也没关系,在写代码时,只需要用一个callback函数代替就可以了。

# 定义回调函数
def callback(value):
	print(value)

案例一:trackBar控件调整图片颜色

学习过计算机视觉我们都知道不同的颜色实际上都是bgr三种颜色混合而成的,在这个案例里面我们通过trackBar控件将bgr设置成刻度条,通过滑动刻度条已形成不同的颜色。

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :Opencv初步学习 
@File    :trackBar案例一:调整图片颜色.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/1/27 19:39 
"""
import cv2
import numpy as np
# 创建窗口
cv2.namedWindow("window",cv2.WINDOW_NORMAL)
cv2.resizeWindow("window",(640,480))

# 定义回调函数
def callback(value):
    print(value)

# 创建三个Trackbar控件
cv2.createTrackbar("R","window",0,255,callback)
cv2.createTrackbar("G","window",0,255,callback)
cv2.createTrackbar("B","window",0,255,callback)
# 用np创建一个图像矩阵
image = np.zeros((480,640,3),np.uint8)  # 注意这里的长宽是相反的,3是指通道数,np.uint8指无符号的整数
while True:
    # 获取Trackbar控件的值
    r = cv2.getTrackbarPos("R","window")
    g = cv2.getTrackbarPos("G","window")
    b = cv2.getTrackbarPos("B","window")
    # 用获取的值来生成图片
    image[:] = [r,g,b] # 替换像素
    # 显示图片
    cv2.imshow("window",image)
    if cv2.waitKey(1) == ord("q"):
        break


cv2.destroyAllWindows()

在这里插入图片描述
调整BGR三个刻度条的值,下面的图片颜色就会发生变化,这是trackBar最基本的案例,创建控件,获得控件的值,循环不断显示图片。这就是这个程序所做的,代码很简单,但是功能很强大!

案例二:trackBar控件调整Canny算子参数

将高斯模糊的高斯核和canny算子阈值的最大值最小值设为三个trackBar控件,探究这三个参数变化对图片产生的影响。完成代码和readme.md上传网盘,需要的同学可以自取:链接:https://pan.baidu.com/s/15IKTeFxVr6_VYnPD_IggTA?pwd=8b7k
提取码:8b7k
注意程序运行方式不是右键运行,而是在终端输入:

python find_edges.py image.jpg

程序主要是由两个py文件组成:find_edges.py和guiutils.py
find_edges.py:

"""
How to run:
python find_edges.py <image path>
"""

import argparse
import cv2
import os

from guiutils import EdgeFinder


def main():
    parser = argparse.ArgumentParser(description='Visualizes the line for hough transform.')
    parser.add_argument('filename',default="ICEWS18")

    args = parser.parse_args()

    img = cv2.imread(args.filename, cv2.IMREAD_GRAYSCALE)

    cv2.imshow('input', img)

    edge_finder = EdgeFinder(img, filter_size=13, threshold1=28, threshold2=115)

    print ("Edge parameters:")
    print ("GaussianBlur Filter Size: %f" % edge_finder.filterSize())
    print ("Threshold1: %f" % edge_finder.threshold1())
    print ("Threshold2: %f" % edge_finder.threshold2())

    (head, tail) = os.path.split(args.filename)

    (root, ext) = os.path.splitext(tail)

    smoothed_filename = os.path.join(root + "-smoothed" + ext)
    edge_filename = os.path.join(root + "-edges" + ext)

    cv2.imwrite(smoothed_filename, edge_finder.smoothedImage())
    cv2.imwrite(edge_filename, edge_finder.edgeImage())
    print(smoothed_filename)

    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

guiutils.py:

import cv2


class EdgeFinder:
    def __init__(self, image, filter_size=1, threshold1=0, threshold2=0):
        self.image = image
        self._filter_size = filter_size
        self._threshold1 = threshold1
        self._threshold2 = threshold2

        def onchangeThreshold1(pos):
            self._threshold1 = pos
            self._render()

        def onchangeThreshold2(pos):
            self._threshold2 = pos
            self._render()

        def onchangeFilterSize(pos):
            self._filter_size = pos
            self._filter_size += (self._filter_size + 1) % 2
            self._render()

        cv2.namedWindow('edges')

        cv2.createTrackbar('threshold1', 'edges', self._threshold1, 255, onchangeThreshold1)
        cv2.createTrackbar('threshold2', 'edges', self._threshold2, 255, onchangeThreshold2)
        cv2.createTrackbar('filter_size', 'edges', self._filter_size, 20, onchangeFilterSize)

        self._render()

        print ("Adjust the parameters as desired.  Hit any key to close.")

        cv2.waitKey(0)

        cv2.destroyWindow('edges')
        cv2.destroyWindow('smoothed')

    def threshold1(self):
        return self._threshold1

    def threshold2(self):
        return self._threshold2

    def filterSize(self):
        return self._filter_size

    def edgeImage(self):
        return self._edge_img

    def smoothedImage(self):
        return self._smoothed_img

    def _render(self):
        self._smoothed_img = cv2.GaussianBlur(self.image, (self._filter_size, self._filter_size), sigmaX=0, sigmaY=0)
        self._edge_img = cv2.Canny(self._smoothed_img, self._threshold1, self._threshold2)
        cv2.imshow('smoothed', self._smoothed_img)
        cv2.imshow('edges', self._edge_img)

在这里插入图片描述
这样我们就可以实时调整卷积核大小和最大阈值和最小阈值,图片实时更新,是不是非常方便?

案例三:trackBar控件调整图像融合参数

在Opencv中提供了图像融合的APIcv2.addWeighted,图像融合不是简单的加法,相当于拿图片做了线性运算new_img = img1w1+img2w2+bias
cv2.addWeighted(src1,alpha,src2,beta,gamma)

  • src1:第一张图片
  • alpha:第一张图片的权重
  • src2:第二张图片
  • beta:第二张图片的权重,没有要求两个权重加起来是1,但1的效果要好一点
  • gamma:偏差b,可以理解为调节明亮度

在进行融合的时候,也要保证两张图片的尺寸一样。在融合中图片所占的权重对最终的图片有很大影响,我们可以用trackBar控件对两个权重做可视化处理。

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :Opencv初步学习 
@File    :案例三图像融合.py
@IDE     :PyCharm 
@Author  :咋
@Date    :2023/1/27 20:21 
"""
import cv2
# 设置窗口大小
cv2.namedWindow("window",cv2.WINDOW_NORMAL)
cv2.resizeWindow("window",(640,480))
# 读取图片
dog = cv2.imread("dog.jpg")
cat = cv2.imread("cat.jpg")
dog = cv2.resize(dog,(400,500))
cat = cv2.resize(cat,(400,500))


# 定义回调函数
def callback(value):
    print(value)

# 创建Trackbar控件
cv2.createTrackbar("weight_dog","window",0,100,callback)
cv2.createTrackbar("weight_cat","window",0,100,callback)


while True:
    # 获取Trackbar控件的值
    weight_dog = cv2.getTrackbarPos("weight_dog","window")
    weight_cat = cv2.getTrackbarPos("weight_cat","window")

    # 图像融合
    add_dog_cat = cv2.addWeighted(dog, weight_dog/100, cat, weight_cat/100, 0)
    # 显示图片
    cv2.imshow("window",add_dog_cat )
    if cv2.waitKey(1) == ord("q"):
        break


cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

通过上面的gif可以看到,调高dog的权重,dog的图片会更清楚,调高cat的权重,cat的图片会更清楚,这样动态的调整十分方便,不用一个数字一个数字去试了

trackBar控件总结

通过这三个案例的学习,相信你对trackbar控件有了更深刻的理解,合理运用trackbar控件将会极大地加快你调参的速度,达到事半功倍的效果!这三个例子只是起到抛砖引玉的效果,在之后的项目中,你也可以把这种发放引入到你的工程中!
好啦,今天的分享就到这里,感兴趣的小伙伴欢迎私信博主或者评论交流哦!

原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

👍 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的咋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值