opencv制作简易RGB阈值编辑器(只用createTrackbar(),没用QT)

最近在学习c++版本的opencv,之前用openmv的ide自带了一个阈值编辑器,就想能不能用opencv复刻,正好也在做rm的目标追踪

先看效果

opencv制作简易RGB阈值编辑器

 (途中橙子在res窗口为白色)

通过拖动滑块,可以分别调整RGB三个通道的上限和下限,得到二值化图像(满足条件为白)

这两个窗口都是视频流,可以很清楚的调整被测物体的位置

源代码:

#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
/*三种颜色的上限和下限6个值*/
int red_lower_pos = 0;
int green_lower_pos = 0;
int blue_lower_pos = 0;
int red_upper_pos = 255;
int green_upper_pos = 255;
int blue_upper_pos = 255;
/*滑块控件函数,pos是滑动的值,赋值给颜色值*/
void onChangeTrackBar_red_lower(int pos, void*) { red_lower_pos = pos; }
void onChangeTrackBar_red_upper(int pos, void*) { red_upper_pos = pos; }
void onChangeTrackBar_green_lower(int pos, void*) { green_lower_pos = pos; }
void onChangeTrackBar_green_upper(int pos, void*) { green_upper_pos = pos; }
void onChangeTrackBar_blue_lower(int pos, void*) { blue_lower_pos = pos; }
void onChangeTrackBar_blue_upper(int pos, void*) { blue_upper_pos = pos; }
int main()
{
    VideoCapture capture(0);
    bool flag = true;
    //标志位,目的是让创建滑块的函数只运行一次
    
    for (;;) {
        Mat frame,res;
        capture >> frame;
        namedWindow("capture");
        imshow("capture", frame);
        if (flag) {
            /*创建滑块*/
            createTrackbar("red_lower_pos", "capture", &red_lower_pos, 255,onChangeTrackBar_red_lower);
            createTrackbar("red_upper_pos", "capture", &red_upper_pos, 255,onChangeTrackBar_red_upper);
            createTrackbar("green_lower_pos", "capture", &green_lower_pos, 255, onChangeTrackBar_green_lower);
            createTrackbar("green_upper_pos", "capture", &green_upper_pos, 255, onChangeTrackBar_green_upper);
            createTrackbar("blue_lower_pos", "capture", &blue_lower_pos, 255, onChangeTrackBar_blue_lower);
            createTrackbar("blue_upper_pos", "capture", &blue_upper_pos, 255, onChangeTrackBar_blue_upper);
            flag = false;
        }
        inRange(frame, Scalar(blue_lower_pos, green_lower_pos, red_lower_pos), Scalar(blue_upper_pos, green_upper_pos, red_upper_pos), res);
        //通过inRange函数生成阈值筛选二值化后的图像
        imshow("res", res);
        if (waitKey(20) == 'q')
            break;
    }
    destroyAllWindows();

    return 0;
}

代码解析:

CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,
                              int* value, int count,
                              TrackbarCallback onChange = 0,
                              void* userdata = 0);
/*trackbarname:滑块命名*/
/*winname:     窗口名称*/
/*value:这是一个指针,可以理解为滑块的初始位置*/
/*count:       滑块长度*/
/*TrackbarCallback onChange:这是一个函数
使用时需要建立一个函数onChangeTrackBar,在这个函数里获得pos的值*/
/*userdata:可传入任意类型指针,哥们c++不行不太会用这个*/

这里着重说一下onChangeTrackBar函数,方便c++基础不好的同学理解

建立一个void函数这个函数的参数是固定死的,长这样

void myTrackbarCallback(int pos, void* userdata);

(函数名随意)

建立好之后,我们就可以通过读取pos的值来获得滑块的值,像这样:

void onChangeTrackBar_red_lower(int pos, void*) { red_lower_pos = pos; }

 然后把这个函数的函数名传入createTrackbar里,像这样:

 createTrackbar("red_lower_pos", "capture", &red_lower_pos, 255,onChangeTrackBar_red_lower);

这样子就能通过滑块给任意变量赋值了。

还有createTrackbar生成完滑块后,生成的窗口跟视频流没关系了,会在每次滑块变动时候调用onChangeTrackBar,这里相当于一个事件

所以createTrackbar只要调用一次就行了,每次循环调用的话会不断刷新,卡死

之后就是使用inRange函数生成二值化之后的图像了,关于inRange:

CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb,
                          InputArray upperb, OutputArray dst);
/*src:输入,为Mat类*/
/*lowerb:RGB下限,为Scalar(b,g,r)*/
/*upperb:RGB上限,为Scalar(b,g,r)*/
/*dst:输出,为Mat类*/

 然后把得到的dst imshow就可以了

代码量不多,我看很多教程用的是QT,感觉还挺麻烦

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值