OpenCV 系列 --- 交互(一)滑动条

对图像处理来说,很多时候需要与用户进行交互,最典型的应用有两种:

(1) 在算法设计时,要根据某一参数的不同取值来进行相应的计算;

(2) 交互式分割算法

其中,对第1种情况而言,OpenCV提供了滑动条,可以灵活地设置参数值来进行相应的处理。而对第2种情况而言,则提供了鼠标交互,首先我们介绍关于滑动条的知识点,下文将会给出鼠标的相关知识点。

  1. 为了更好地说明滑动条的应用,我采用Canny边缘检测算法来进行演示,其调用方式为:
void Canny(InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false )

其中,image代表输入图像,这里为单通道图像;edges为单通道的边缘图;threshold1与threshold2是Canny边缘检测算法的两个阈值;apertureSize与L2gradient有默认值,因此在这篇文章里不进行解释,感兴趣的可以去官方网站查询。

  1. 对滑动条来说,其函数调用方式为:
int createTrackbar(const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)

关于这几个参数的解释如下:
* trackbarname: 滚动条的名字,通常指滚动条前的一串字符
* winname:滚动条所在窗口的名字,这个其实是定义了滚动条所依赖的主窗口的名字
* value:滑块的位置,在创建时,此值即为初始值
* count:滑块的最大值,对滑块来说,最小值始终为0
* TrackbarCallback:这个是最核心的,指向回调函数的指针,当滑块位置改变时,就会调用指向的函数,从而达到交互的目的
* userdata:默认值为0。此值是用户传给回调函数的值,用来进行相应的处理。如果value的值设置为全局变量,则滑动块的值可以由value来进行控制,可以不设置userdata

  1. 测试用的完整代码如下:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

Mat imgSrc;//输入图像,彩色
Mat imgEdge;//边缘图像
Mat imgGray;//输入图像,灰度图像

const int g_nMaxThresh = 255;
int g_nThresh_low;
int g_nThresh_high;

void on_Trackbar(int,void*);

int main()
{
    imgSrc = imread("running.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);

    cvtColor(imgSrc, imgGray, CV_RGB2GRAY);//彩色图像转换为灰度图

    g_nThresh_low  = 0;//初始化低阈值值0
    g_nThresh_high = 0;//初始化高阈值为0

    namedWindow("Edge Detection", WINDOW_AUTOSIZE);//生成主窗口,用来容纳滚动条与图像
    imshow("Edge Detection", imgGray);

//创建一个滑动条,名字为Low:255,主窗口为Edge Detection,最大值为255,value为g_nThresh_low,回调函数为on_trackbar
    createTrackbar("Low: 255", "Edge Detection", &g_nThresh_low, 255, on_Trackbar);

//创建一个滑动条,名字为High: 255,主窗口为Edge Detection,最大值为255,value为g_nThresh_high,回调函数为on_trackbar  
    createTrackbar("High: 255", "Edge Detection", &g_nThresh_high, 255, on_Trackbar);

    waitKey(0);
    return 0;
}
//回调函数
void on_Trackbar(int, void*)
{
    cout << "Threshold value: " <<endl;
    cout << "High: " << g_nThresh_high << endl;
    cout << "Low: " << g_nThresh_low << endl << endl;

//调用Canny边缘检测算法,imgGray为输入图像,imgEdge为边缘图像,g_nThresh_low与g_nThresh_high是两个阈值
    Canny(imgGray, imgEdge, g_nThresh_low, g_nThresh_high);

    imshow("Edge Detection", imgEdge);
}
  1. 程序运行结果
    拖动滑动条的位置,在阈值改变时,程序可以实时地得到边缘检测的效果

    • 程序的初始窗口如下:

    • 拖动滑动条,改变高低阈值,低阈值设置为16,高阈值设置为38,结果如下:

    • 拖动滑动条,改变高低阈值,低阈值设置为194,高阈值设置为208,结果如下:
      这里写图片描述

可以看出,不同的高低阈值可以得到不同的边缘检测效果。对我来说,现在在采用边缘检测结果时,基本不会用这些基本的边缘检测算法,我会用一些比较近代的边缘检测算法,比如Structured forest等算法,效果很不错。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值