OpenCV4(C++)—— 创建窗口滑动条来调参


创建滑动条 —— createTrackbar

createTrackbar是OpenCV中的一个函数,用于创建一个可调节的滑动条(Trackbar),以便在图像处理过程中实时调整参数

 int cv::createTrackbar(const String & trackbarname,  // 滑动条的名称,作为字符串传递
                        const String & winname,  // 滑动条的窗口名称,通常是显示图像的窗口名称
                        int * value,  // 指向整数变量的指针,该指针指向的值反映滑块的位置,创建后,滑块位置由此变量定义
                        int  count,  // 滑动条的最大取值
                        TrackbarCallback onChange = 0,  // 回调函数:每次滑块更改位置时要调用的函数的指针
                        void * userdata = 0  // 传递给回调函数的可选参数
                            )
其中回调函数的定义如下:
  void onChange(int value, void* userdata)   // void* userdata 参数是可选的
  {
    // 滑动条值发生变化时执行的操作
  }

可以看到,回调函数是可选参数,当默认为0时,则只更新value,要进行的操作在后面定义

例:二值化,选择参数阈值作为滑动条

#include <opencv2/opencv.hpp>
#include<iostream>  
using namespace std;

int main()
{
    cv::Mat image = cv::imread("C:/Users/Opencv/temp/lena.png");

    if (image.empty()) {
        cout << "打开图片失败" <<endl;
        return -1;
    }

    cv::namedWindow("img");
    cv::imshow("img", image);
    int value = 128;

    cv::createTrackbar("阈值", "img", &value, 255);

    while (true)
    {
        cv::Mat thrseImg;
        cv::threshold(image, thrseImg, value, 255, cv::THRESH_BINARY);
        cv::imshow("img", thrseImg);  // 注意:窗口的名字要和之前的一样
        //cv::imshow("取不同名字时", thrseImg);  

        char key = cv::waitKey(10);
        if (key == 27 || key == 'q')
        {
            break;
        }
    }
    
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

注:上述代码中,如果while循环里imshow展示的窗口名字跟之前不同,则会新开这个窗口作为滑动结果窗口,如下图所示,在原图img中滑动数值,原图不会改变,改变的是另一个窗口。

在这里插入图片描述
使用回调函数,来简化上述代码

#include <opencv2/opencv.hpp>
#include<iostream>  

using namespace std;

void callback(int value, void*);
cv::Mat image ,thrseImg;   // 定义成全局变量,才能同时在回调函数中调用

int main()
{
    image = cv::imread("C:/Users/jutze/ljw_C++/Opencv/temp/lena.png");

    if (image.empty()) {
        cout << "打开图片失败" <<endl;
        return -1;
    }

    cv::namedWindow("img");
    cv::imshow("img", image);

    int value = 128;

    cv::createTrackbar("阈值", "img", &value, 255, callback);
    
    cv::waitKey(0);
    cv::destroyAllWindows();
    return 0;
}

static void callback(int value, void*)
{
    cv::threshold(image, thrseImg, value, 255, cv::THRESH_BINARY);
    cv::imshow("img", thrseImg);
}

此外,OpenCV还提供了鼠标响应函数setMouseCallback()和键盘响应函数setKeyboardCallback(),通过在指定窗口进行鼠标点击或键盘按键,来触发回调函数,执行相关操作。但感觉实际使用的场景比较少,以后遇到再说吧。

再来一个python的例子,调整亮度对图片的影响

def aug_ok1(img, mask, brightness_value):
    # 定义图像增强的变换列表
    transform_ok = [
        # A.ChannelShuffle(p=1),
        A.RandomBrightnessContrast(brightness_limit=(brightness_value, brightness_value), contrast_limit=0, p=1)
    ]

    transform_ok = A.Compose(transform_ok)

    # 应用变换到图像和掩膜
    transformed = transform_ok(image=img, mask=mask)
    image = transformed["image"]
    mask = transformed["mask"]
    return image, mask

def on_brightness_change(value):
    # 将滑动条值映射到范围 [-0.8, 0.8]
    brightness_value = value / 100.0 * 1.6 - 0.8

    # 调用图像增强函数
    img1, _ = aug_ok1(img, label, brightness_value)

    # 在窗口中显示图像
    cv2.imshow("img1", img1)

if __name__ == "__main__":
    img = cv2.imread('C:/Users/WA.jpg')
	label = cv2.imread('C:/Users/WA.jpg', 0)
    # 创建窗口并命名
    cv2.namedWindow("img1")

    # 创建滑动条
    cv2.createTrackbar("Brightness", "img1", 0, 100, on_brightness_change)

    # 初始化滑动条的初始值
    cv2.setTrackbarPos("Brightness", "img1", 50)

    # 显示原始图像
    cv2.imshow("img", img)

    # 等待按下Esc键退出
    while cv2.waitKey(1) != 27:
        pass
    cv2.destroyAllWindows()
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个基于C++OpenCV的直线检测程序,其中包含滑动调参功能。 ```c++ #include <opencv2/opencv.hpp> using namespace cv; Mat src, dst; int lowThreshold = 50, highThreshold = 150; const int max_lowThreshold = 1000, max_highThreshold = 3000; const int max_nLineGap = 100, max_nMinLineLength = 100; const int max_rho = 100, max_theta = 180; int nLineGap = 10, nMinLineLength = 50; int rho = 1, theta = 1; void CannyThreshold(int, void*); void HoughLinesThreshold(int, void*); int main() { src = imread("test.jpg", IMREAD_GRAYSCALE); if (src.empty()) { printf("can not open the image!\n"); return -1; } namedWindow("src", WINDOW_NORMAL); imshow("src", src); namedWindow("dst", WINDOW_NORMAL); createTrackbar("Min Threshold:", "dst", &lowThreshold, max_lowThreshold, CannyThreshold); createTrackbar("Max Threshold:", "dst", &highThreshold, max_highThreshold, CannyThreshold); createTrackbar("Line Gap:", "dst", &nLineGap, max_nLineGap, HoughLinesThreshold); createTrackbar("Min Line Length:", "dst", &nMinLineLength, max_nMinLineLength, HoughLinesThreshold); createTrackbar("rho:", "dst", &rho, max_rho, HoughLinesThreshold); createTrackbar("theta:", "dst", &theta, max_theta, HoughLinesThreshold); CannyThreshold(0, 0); HoughLinesThreshold(0, 0); waitKey(0); return 0; } void CannyThreshold(int, void*) { Canny(src, dst, lowThreshold, highThreshold); imshow("dst", dst); } void HoughLinesThreshold(int, void*) { Mat cdst; cvtColor(dst, cdst, COLOR_GRAY2BGR); vector<Vec2f> lines; HoughLines(dst, lines, rho, CV_PI / theta, nMinLineLength, nLineGap, 0, 0); for (size_t i = 0; i < lines.size(); i++) { float rho = lines[i][0], theta = lines[i][1]; Point pt1, pt2; double a = cos(theta), b = sin(theta); double x0 = a * rho, y0 = b * rho; pt1.x = cvRound(x0 + 1000 * (-b)); pt1.y = cvRound(y0 + 1000 * a); pt2.x = cvRound(x0 - 1000 * (-b)); pt2.y = cvRound(y0 - 1000 * a); line(cdst, pt1, pt2, Scalar(0, 0, 255), 3, LINE_AA); } imshow("dst", cdst); } ``` 这段代码中,我们使用了 `createTrackbar` 函数来创建滑动条,它们的值将用于调整Canny边缘检测和霍夫直线检测算法的阈值、线段间隔、最小线段长度、rho和theta值。 在 `main` 函数中,我们通过 `imread` 函数读取输入图像,然后创建了两个窗口,一个用于显示原始图像,另一个用于显示检测到的直线。 在 `CannyThreshold` 函数中,我们使用 `Canny` 函数进行边缘检测,并将结果显示在 `dst` 窗口中。 在 `HoughLinesThreshold` 函数中,我们首先将 `dst` 转换为三通道图像 `cdst`,然后使用 `HoughLines` 函数进行霍夫直线检测,并在 `cdst` 中绘制检测到的直线。 最后,我们在 `main` 函数中调用 `CannyThreshold` 和 `HoughLinesThreshold` 函数,以便在程序启动时显示一组初步检测到的直线,用户可以通过滑动条调整参数以更好地检测直线。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想要躺平的一枚

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

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

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

打赏作者

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

抵扣说明:

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

余额充值