很多情况下个人更多用QT搭配opencv进行一系列开发,QT可以迅速开发出合乎要求的界面。但是实际上,试验过程中并不需要一个美观且功能齐全的界面,使用opencv进行图像处理,可能反反复复使用的是按键、勾选按钮、图片显示、参数修改或者显示等功能,这些小功能似乎没必要动用QT的牛刀。
有一个非常小巧的GUI库,CVUI。它是建立在OpenCV绘图基元之上的,除OpenCV之外,没有任何依赖性。而使用它只需要包含一个头文件即可,具有非常好的跨平台特性。
这是它的官方网站
接下来使用最新的 2.7.0 版本进行使用总结,配合使用官方例子。
目录
1 使用前的准备
2 显示图片
3 按键
4 文字/变量显示
5 文字显示
6 滑动条控制变量
7 鼠标位置与点击事件
8 复选框
9 画中画,添加图片
10 计数器
11 其他
12 小建议
1 使用前的准备
下载头文件 cvui.h ,添加到项目中,在需要使用GUI的源文件添加如下代码:
#define CVUI_IMPLEMENTATION
#include <cvui.h>
注意:并不是在H头文件中进行添加,如果有多个 CPP文件使用GUI功能,则均添加(宏定义可以只添加一次)。
2 显示图片
CVUI与opencv一样,使用imshow进行显示:
//hello-world例子
//cv::imshow(WINDOW_NAME, imageOut);
cvui::init(WINDOW_NAME);//使用一个CVUI窗体前,必须输入窗体名进行初始化
cvui::imshow(WINDOW_NAME, imageOut);//窗体显示,格式同cv函数
注意:初始化是必须滴。
3 按键
按键的显示与按键状态使用同一个函数:
//hello-world例子
//在imageOut中添加一个按键,显示内容为“Hello,world!”
cvui::button(imageOut, 110, 80, "Hello, world!")
//得到这个按键的状态,如果按下则count值加一
if (cvui::button(imageOut, 110, 80, "Hello, world!")) {
// The button was clicked, so let's increment our counter.
count++;
}
//函数原型,可以查看h文件298行了解更详细的信息
bool button(cv::Mat& theWhere, int theX, int theY, const cv::String& theLabel);
bool button(cv::Mat& theWhere, int theX, int theY, int theWidth, int theHeight, const cv::String& theLabel);
bool button(cv::Mat& theWhere, int theX, int theY, cv::Mat& theIdle, cv::Mat& theOver, cv::Mat& theDown);
4 文字/变量显示
CVUI很关心我们的编程习惯,认为同时显示字符串和变量是一件很麻烦的事情,于是就有了一个和C语言printf函数很像的函数:
//hello-world例子
//显示字符串加变量
// Sometimes you want to show text that is not that simple, e.g. strings + numbers.
// You can use cvui::printf for that. It accepts a variable number of parameter, pretty
// much like printf does.
// Let's show how many times the button has been clicked.
cvui::printf(imageOut, 250, 90, 0.4, 0xff0000, "Button click count: %d", count);
//用于在imageOut显示一行字符串和变量值,0xff0000显然为颜色红,具体看H文件391行
5 文字显示
使用的是:text函数,与printf不同的是,不能显示变量而已。
//例子trackbar
//函数原型,详见H头文件372行
void text(cv::Mat& theWhere, int theX, int theY, const cv::String& theText, double theFontScale = 0.4, unsigned int theColor = 0xCECECE);
//参数依次为
//theWhere:输入图像
//theX:X坐标
//theY:Y坐标
//theText:文本内容
//theFontScale:文本尺寸
//theColor:颜色
//显示实例中的文本内容,在(x,10)处
cvui::text(imageOut, x, 10, "double, step 1.0 (default)");
6 滑动条控制变量
使用trackbar函数得到滑动条。
//例子trackbar
//函数原型,详见H头文件475行
bool trackbar(cv::Mat& theWhere, int theX, int theY, int theWidth, T *theValue, T theMin, T theMax, int theSegments = 1, const char *theLabelFormat = "%.1Lf", unsigned int theOptions = 0, T theDiscreteStep = 1);
//参数有些多,依次为
//theWhere :输入的图像
//theX :X坐标
//theY :Y坐标
//theWidth :宽度
//theValue :滑动条初始值
//theMin :滑动条最小值
//theMax :滑动条最大值
//theSegments :滑动条标签数,0/1为只有首尾标签,2为多一个中间刻度,以此类推
//theLabelFormat :精度,默认为0.1
//theOptions :滑动条可选参数
//theDiscreteStep :步进值,最小刻度值,搭配可选参数使用
//实例中滑动条的使用
//在(x,40)处生成一个宽度为width、初始值为doubleValue、首为0.0、尾为100.0的滑动条
cvui::trackbar(imageOut, x, 40, width, &doubleValue, (double)0., (double)100.);
//在(x,80)处生成一个首为10.0、尾为15.0的滑动条,默认精度
cvui::trackbar(imageOut, x, 80, width, &floatValue, (float)10., (float)15.);
//在(x,120)处生成一个首为0.00、尾为20.00的滑动条,精度为两个小数点
cvui::trackbar(imageOut, x, 120, width, &doubleValue2, (double)0., (double)20., 4, "%.2Lf");
//在(x,160)处生成一个首为0、尾为255的滑动条,精度为0个小数点即1
cvui::trackbar(imageOut, x, 160, width, &ucharValue, (uchar)0, (uchar)255, 0, "%.0Lf");
//在(x,200)处生成一个首为10.0、尾为10.5的滑动条,默认精度,设置滑动条滑动不连续且步进值0.1
cvui::trackbar(imageOut, x, 200, width, &doubleValue3, (double)10., (double)10.5, 1, "%.1Lf", cvui::TRACKBAR_DISCRETE, (double)0.1);
//在(x,240)处生成一个首为10、尾为50的滑动条,精度为1,设置为滑动不连续且隐藏除首尾标签,步进2
cvui::trackbar(imageOut, x, 240, width, &intValue, (int)10, (int)50, 3, "%.0Lf",
cvui::TRACKBAR_DISCRETE | cvui::TRACKBAR_HIDE_SEGMENT_LABELS, (int)2);
//在(x,280)处生成一个首为-128、尾为127的滑动条,加中间刻度,精度为1
cvui::trackbar(imageOut, x, 280, width, &charValue, (char)-128, (char)127, 2, "%.0Lf");
一般可选参数与步进参数搭配使用。可选参数如下:
// Constants regarding components
const unsigned int TRACKBAR_HIDE_SEGMENT_LABELS = 1; //隐藏添加的标签
const unsigned int TRACKBAR_HIDE_STEP_SCALE = 2; //隐藏步进刻度
const unsigned int TRACKBAR_DISCRETE = 4; //滑动条不连续(锁定刻度滑动)
const unsigned int TRACKBAR_HIDE_MIN_MAX_LABELS = 8; //隐藏首尾刻度标签
const unsigned int TRACKBAR_HIDE_VALUE_LABEL = 16; //隐藏值标签
const unsigned int TRACKBAR_HIDE_LABELS = 32; //隐藏标签
当滑动条值区间小时,默认参数会有许多无用的刻度,滑到刻度中间时也不会将值变为中间值。需要选择TRACKBAR_DISCRETE参数搭配设定步进值使用。
7 鼠标位置与点击事件
CVUI有5种方法与鼠标相关,有的是专门用于得到鼠标位置返回值的,有的是用于得到鼠标点击状态的。
//例子mouse
//以下介绍鼠标相关方法,详见H文件219行
//得到鼠标在图像中的位置
cv::Point mouse(const cv::String& theWindowName = "");
//实例如下,得到鼠标在当前图像坐标
cvui::printf(imageOut, cvui::mouse().x , cvui::mouse().y , 0.3, 0xff0000, "x:%d, y:%d",
cvui::mouse().x,cvui::mouse().y);
//得到鼠标状态
bool mouse(int theQuery);
//状态有: `cvui::DOWN`, `cvui::UP`, `cvui::CLICK`, and `cvui::IS_DOWN`
if (cvui::mouse(cvui::IS_DOWN)) { }
//得到某一窗口的鼠标状态
bool mouse(const cv::String& theWindowName, int theQuery);
//得到某一按键的状态
bool mouse(int theButton, int theQuery);
//按键为: `cvui::LEFT_BUTTON`, `cvui::MIDDLE_BUTTON` 、`cvui::LEFT_BUTTON`
//得到某一窗口上某一按键的状态
bool mouse(const cv::String& theWindowName, int theButton, int theQuery);
可见,虽然有扩张的5种方法,但是功能大同小异,用的时候也很容易使用不同的方法达到寄几的目的。
8 复选框
CVUI提供了复选框函数checkbox,使用上和按键类似。
//例子canny
//复选框,详见H头文件358行
bool checkbox(cv::Mat& theWhere, int theX, int theY, const cv::String& theLabel, bool
*theState, unsigned int theColor = 0xCECECE);
/**
显示一个复选框。 您可以使用返回值来监视是否复选框是否已选中。
theWhere 图像
theX X坐标
theY Y坐标
theLabel 复选框显示的文本
theState 初始化参数,true或false
theColor 颜色
返回值: 返回复选框的值,勾选为true,未勾选为false
*/
9 画中画,添加图片
我们需要在一幅图上显示另外一幅图时,可以使用CVUI的image方法。当然opencv也可以很轻松通过ROI实现这一功能。
//图像上的特定位置加入另一张图片,详见H头文件344行
void image(cv::Mat& theWhere, int theX, int theY, cv::Mat& theImage);
/**
显示一张图片
theWhere 原图
theX X坐标
theY Y坐标
theImage 需要放进去的图
**/
需要注意的是,放进去的图不能超过原图的边界,不然会报错,因此在放入之前resize一下比较保险。
10 计数器
计数器就是带有上下按键,可以步进调整数值的玩意。CVUI中的函数为counter。
//计数器,详见H头文件424行
//整数步进加减
int counter(cv::Mat& theWhere, int theX, int theY, int *theValue, int theStep = 1, const
char *theFormat = "%d");
//浮点数步进加减
double counter(cv::Mat& theWhere, int theX, int theY, double *theValue, double theStep =
0.5, const char *theFormat = "%.2f");
//我已无力去解释一个个参数,按照需要修改默认值就行了,搭配文字显示可能更好
11 其他
已经介绍了十个好用或者说经常会碰到的UI了,还有其他好东西。
sparkline :显示向量数组值,画出分布线
rect : 画一个矩形,可以设置框颜色和填充色(可以用矩形做底,制作出层次分明的UI)
iarea : 设定一个不显示的矩形区域,跟踪鼠标状态,返回四种状态值
beginRow/endRow : 控件的自动排布功能
。。。
12 小建议
使用CVUI,可以先设计好想要的UI图,再将显示的图往上贴。
官方例子建议显示前使用 cvui::update(); 进行更新,避免出现乱七八糟的问题。
例如CheckBox,如果想改变大小,得去1713行改动源码,灵活运用。
对性能的影响上还没有进行测试,有相关结果会连同一个小demo一起发出来。