简介
本设计的GUI其实是由一个用户界面demo开发而成,主要由弹窗以及主界面组成。弹窗主要用于提示用户操作,为用户提供选择;主界面用于交互功能的实现。
外观设计
外观设计部分大部分在Qt Designer上完成。将所需控件按照方案论证中的布局图拖动至预设位置,并根据对应的功能对其合适的命名以方便后续程序的编写。接着选择合适的Layout类型控制各控件的布局,如在按键较密集的功能选择区采用网格布局,使其中的按钮整齐排列。接着在合适的位置添加Spacer控件,这个控件可以控制各控件间的距离以达到窗口缩放时界面布局随之缩放的目的。处理好布局后,在iconfont中找到风格统一的矢量图作为各按键的图标。
除此之外,部分外观优化也通过QSS在类函数中完成。我们在Widget和MyMessageBox类中定义了用于设置窗口stylesheet的initUi函数,其中使用setAttribute (Qt:: WA_TranslucentBackground , true)使得窗口透明等美化语句。同时也在MyMessageBox类中定义setIcon函数,实现根据弹窗类型设置合适的弹窗图标的功能。
至此,我们得到如下的ui界面。
逻辑设计
GUI的逻辑设计主要涉及一下模块。
1)Qt控件与程序代码的关联
通常这一功能主要由QObject::connect函数实现,这一方法需要在主窗口类的构造函数显式声明,不够简洁。本设计中我们将按键(如pushBtn)对应的槽函数命名为on_pushBtn_clicked,它是QtCreator默认的按键关联写法,编译时自动
此外,程序也使用自定义的信号槽Q_SIGNALS的功能实现代码与控键的关联,如将ROI截取函数与后续处理的函数关联起来。首先需要在helper类中定义一个信号函数void signalCompleteCature(int x, int y, int h, int w)。后续重写的键盘事件中,函数将调用此函数发出信号,返回用户选定的ROI信息。而在Widget类的onCatureImage()函数中,同样使用connect函数实现关联,其中需要设置信号signal为signalCompleteCature函数,对应槽slot为用于后续处理的onCompleteCature函数。
2)程序使用中相关信息的存储
本程序处理过程中涉及了处理前的前景图像,选定的背景图像,抠图过程得到的掩码以及抠图结果等图像矩阵,这些信息都可以直接创建类属性进行存储。值得注意的是Widget类中的scale属性以及helper类中的imgPos和labelCenter属性,它们是ROI截取过程中重要的信息。由于控件大小与原始图像大小不一样,程序需要记录界面中显示图像相对于原图的缩放比例,进而对后续截取到的ROI进行比例换算。而imgPos和labelCenter则用于判断截取时鼠标是否超出图像范围以及ROI在待操作图像的像素坐标系中位置的计算。
3)图像文件的打开与保存
首先使用QFileDialog::getSaveFileName函数获得目的路径并转化为string类型,再通过cv::imread或cv::imwrite打开或保存图像。需要注意的是若需要在读入图像后将其显示于QLabel上,则需要对图像格式进行转换。由于OpenCV中对彩色图像的默认保存格式为BGR,而Qt中的QImage需要的彩色图像格式为RGB,所以需要使用cvtColor函数将Mat类型变量的格式转换为RGB才能构造对应的QImage变量。得到QImage类型变量后,还需要根据QLabel的大小将其resize,注意使用参数Qt::KeepAspectRatio以保证缩放前后图像的长宽比例保持不变。最后结合使用setPixmap与QPixmap::fromImage函数即可实现图像显示功能。
4)截取待操作图片的ROI
这一功能涉及了helper和Widget两个类。首先是helper类,它继承自QWidget类,构造函数包含待操作图像的位置中心point以及大小size参数,通过它们,程序可以计算出整幅图像在屏幕中的范围。同时还需要使用grabWindow函数截取当前屏幕的图片,而后续操作都是在这张屏幕截图上进行的。接着重写鼠标事件以及paintEvent实现鼠标左键按下拖动时矩形框的绘制与ROI位置计算的功能。这一步需要利用构造函数中计算所得的图像范围信息,判断选取的ROI是否超出待操作图像的区域以便在超出时将矩形修正限制于图像范围内,并由鼠标事件记录的矩形框左上角与右下角点计算出ROI在像素坐标系中的位置。然后需要重写keyPressEvent,内部逻辑为:接收到esc输入时放弃ROI选取;接收到回车enter输入时,调用signalCompleteCature函数发出选取结束的信号,并将选取到的ROI信息返回给对应的槽函数Widget::onCompleteCature。回到Widget类中,onCatureImage是用于关联ROI选区抠图按键的函数。其中结合使用了mapToGlobal、QWidget::pos和QWidget::size函数获取QLabel中心(同时也是图像中心)在屏幕中的位置以及待操作图像的大小。根据这两个变量定义helper类对象,并使用connect将signalCompleteCature和onCompleteCature函数关联起来。后者接收到ROI信息后将根据显示的图片相对于原图的缩放比例计算出用户所选区域在原图中的位置与大小。
效果
源码下载
基于opencv和qt的多功能抠图应用