[opencv][cpp] 多窗口多滑动条案例

[opencv][cpp] 多窗口多滑动条案例




1. 两窗口多滑动条

1. 需求

创建两个 cv 窗口用来模拟处理图像 do_thresh,do_other,
窗口 do_thresh 包含两个滑动条 T_ty(0-3),T_th(0-255),
窗口 do_other 包含三个滑动条 T_th1(0-3),T_th2(0-100),T_th3(0-255)。


2. 完整代码

//
// Created by jacob on 12/29/20.
//

#include <iostream>

#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>

using namespace std;
namespace cvlog = cv::utils::logging;


/***-------------------- global variable --------------------***/

cv::Mat src, gray, binary;

double bin_thresh = 0;
int bin_type = 0;
struct BinData {
    int sliderID;
    std::string sliderName;
    int th;
    int ty;
};


int oth_Th1 = 0;
int oth_th2 = 0;
int oth_th3 = 0;
struct OtherData {
    int sliderID;
    std::string sliderName;
    int th1;
    int th2;
    int th3;
};

/***-------------------- callback --------------------***/
void onThresholdBar(int sliderVal, void *userdata) {
    const auto &slider = *static_cast<BinData *>(userdata);
    auto sliderId = slider.sliderID;
    auto sliderName = slider.sliderName;

    int type;
    double thresh;
    if (sliderId == 0) {
        CV_LOG_INFO(NULL, "sliderName: " << sliderName << ", value: " << sliderVal)
//        if(sliderVal == 0){
//
//        }else if(sliderVal == 1){
//
//        }else if(sliderVal == 2){
//
//        }else if(sliderVal == 3){
//
//        }
    } else if (sliderId == 1) {
        CV_LOG_INFO(NULL, "sliderName: " << sliderName << ", value: " << sliderVal)
    } else {
        CV_LOG_INFO(NULL, "ERROR")
    }

    // do processing
    CV_LOG_INFO(NULL, "bin_thresh: " << bin_thresh << ", bin_type: " << bin_type)
    cv::threshold(gray, binary, thresh, 255, type);
}


void onOtherBar(int sliderVal, void *userdata) {
    const auto &slider = *static_cast<BinData *>(userdata);
    auto sliderId = slider.sliderID;
    auto sliderName = slider.sliderName;

    int type;
    double thresh;
    if (sliderId == 0) {
        CV_LOG_INFO(NULL, "sliderName: " << sliderName << ", value: " << sliderVal)
    } else if (sliderId == 1) {
        CV_LOG_INFO(NULL, "sliderName: " << sliderName << ", value: " << sliderVal)
    } else if (sliderId == 2) {
        CV_LOG_INFO(NULL, "sliderName: " << sliderName << ", value: " << sliderVal)
    } else {
        CV_LOG_INFO(NULL, "ERROR")

    }

    // do processing
}


/***-------------------- entry --------------------***/
int main(int argc, char **argv) {

    // setting up cv log
    cvlog::setLogLevel(cvlog::LOG_LEVEL_INFO);

    string filename = "../img/engline.jpg";
    src = cv::imread(filename, cv::IMREAD_COLOR);
    cv::imshow("src", src);

    cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
    cv::imshow("gray", gray);


    // image processing 1.
    cv::namedWindow("do_thresh", cv::WINDOW_AUTOSIZE);

    BinData bType{0, "type", 0, 0};
    cv::createTrackbar("T_ty", "do_thresh", &bType.ty, 3, onThresholdBar, &bType);

    BinData bThresh{1, "thresh", 0, 0};
    cv::createTrackbar("T_th", "do_thresh", &bType.th, 255, onThresholdBar, &bThresh);


    // image processing 2.
    cv::namedWindow("do_other", cv::WINDOW_AUTOSIZE);

    OtherData oThresh1{0, "th1", 0, 0, 0};
    cv::createTrackbar("T_th1", "do_other", &oThresh1.th1, 3, onOtherBar, &oThresh1);

    OtherData oThresh2{1, "th2", 0, 0, 0};
    cv::createTrackbar("T_th2", "do_other", &oThresh2.th2, 100, onOtherBar, &oThresh2);

    OtherData oThresh3{2, "th3", 0, 0, 0};
    cv::createTrackbar("T_th3", "do_other", &oThresh3.th3, 100, onOtherBar, &oThresh2);


    // pending main
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}

3. 演示

在这里插入图片描述


2. 从滑动条回调函数中提取参数

1. 需求

在主函数中得到窗口滑动条位置数据

2. 完整代码

//
// Created by jacob on 12/29/20.
//

#include <iostream>

#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/logger.hpp>

using namespace std;
namespace cvlog = cv::utils::logging;


/***-------------------- global variable --------------------***/

cv::Mat src, gray, binary;

int bin_type = 0;
double bin_thresh = 0;
struct BinData {
    int sliderID;
    std::string sliderName;
    int th;
    int ty;
};


/***-------------------- callback --------------------***/
void onThresholdBar(int sliderVal, void *userdata) {
    const auto &slider = *static_cast<BinData *>(userdata);
    auto sliderId = slider.sliderID;
    auto sliderName = slider.sliderName;

    if (sliderId == 0) {            // type
//        CV_LOG_INFO(CB, "sliderName: " << sliderName << ", value: " << sliderVal)
        if (sliderVal == 0) {
            bin_type = cv::THRESH_BINARY;
        } else if (sliderVal == 1) {
            bin_type = cv::THRESH_BINARY | cv::THRESH_TRIANGLE;
        } else if (sliderVal == 2) {
            bin_type = cv::THRESH_BINARY_INV;
        } else if (sliderVal == 3) {
            bin_type = cv::THRESH_BINARY_INV | cv::THRESH_TRIANGLE;
        }
    } else if (sliderId == 1) {     // thresh
//        CV_LOG_INFO(CB, "sliderName: " << sliderName << ", value: " << sliderVal)
        bin_thresh = double(sliderVal);
    } else {
        CV_LOG_INFO(CB, "ERROR")
    }

    // do processing
    CV_LOG_INFO(CB, "bin_thresh: " << bin_thresh << ", bin_type: " << bin_type)
    cv::threshold(gray, binary, bin_thresh, 255, bin_type);
    cv::imshow("do_thresh", binary);
}


/*
void print_type(){
    CV_LOG_INFO(TYPE, "b_:" << cv::THRESH_BINARY)                                   // 0
    CV_LOG_INFO(TYPE, "b_t:" << (cv::THRESH_BINARY | cv::THRESH_TRIANGLE))          // 16
    CV_LOG_INFO(TYPE, "bi_:" << cv::THRESH_BINARY_INV)                              // 1
    CV_LOG_INFO(TYPE, "bi_t:" << (cv::THRESH_BINARY_INV | cv::THRESH_TRIANGLE))     // 17
}
*/


/***-------------------- entry --------------------***/
int main(int argc, char **argv) {

    // setting up cv log
    cvlog::setLogLevel(cvlog::LOG_LEVEL_INFO);

    string filename = "../img/engline.jpg";
    src = cv::imread(filename, cv::IMREAD_COLOR);
    cv::imshow("src", src);

    cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
    cv::imshow("gray", gray);


    // image processing 1.
    cv::namedWindow("do_thresh", cv::WINDOW_AUTOSIZE);

    BinData btData_type{0, "type", 0};
    cv::createTrackbar("T_ty", "do_thresh", &btData_type.ty, 3, onThresholdBar, &btData_type);

    BinData btData_thresh{1, "thresh", 0};
    cv::createTrackbar("T_th", "do_thresh", &btData_thresh.th, 255, onThresholdBar, &btData_thresh);
    onThresholdBar(0, &btData_type);    // init once is enough

    while (true) {
        int key = cv::waitKey(2);
        if (key == 27) {
            break;
        }

        int ty = cv::getTrackbarPos("T_ty", "do_thresh");
        int th = cv::getTrackbarPos("T_th", "do_thresh");
        CV_LOG_INFO(WHILE, "T_ty: " << ty << ", T_th: " << th)

        cv::imshow("binary_in_while", binary);

    }

    // pending main
    cv::destroyAllWindows();

    return 0;
}

3. 演示

在这里插入图片描述


&& 参考

链接:C++ 结构体初始化与赋值
链接:Callback机制
链接:Trackbar as the Color Palette


&& 问题解决

[待解决][部分解决,章节2] 如何获取滑动条回调函数中的数据?

在这里插入图片描述

  1. 使用全局变量?
  2. 使用 cv api?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值