在实际应用中,为了某种需要,常将多张图合成为一张图,OpenCV库也实现了这类功能。下面通过OpenCV的多图合成技术将两张图合成为一张图。
1.程序界面
创建一个Qt桌面应用程序项目,项目名称为“OpencvBlend”,设计程序界面如图所示。
2.全局变量及方法
为了提高程序代码的使用效率,通常建议将程序中公用的图片对象的句柄声明为全局变量,通用的方法声明为公有(public)方法,定义在项目.h头文件中。
“mainwindow.h”头文件的代码如下:
#include <QMainWindow>
#include <opencv2/opencv.hpp> //OpenCV 文件包含
using namespace cv; //OpenCV命名空间
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void initMainWindow(); // 界面初始化
void imgProc(float alpha); // 处理图片
void imgShow(); // 显示图片
private:
Ui::MainWindow *ui;
Mat myImg; // 缓存图片
QImage myQImg; // 保存图片
};
3.初始化显示
首先在Qt界面上显示待处理的图片,在构造方法中添加如下代码
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
initMainWindow();
}
初始化方法initMainWindow()的代码为:
void MainWindow::initMainWindow()
{
QString imgPath = "shape01.jpg"; //本地路径(图片直接存放在项目目录下)
Mat imgData = imread (imgPath.toLatin1().data()); //读取图片数据
cvtColor(imgData, imgData, COLOR_BGR2RGB); //图片格式转换
myImg = imgData;
myQImg = QImage( (const unsigned char*) (imgData.data), imgData.cols, imgData.rows,
QImage::Format_RGB888);
imgShow(); //显示图片
}
显示图片的imgShow()方法中只有一句:
void MainWindow::imgShow()
{
ui->labView->setPixmap(QPixmap::fromImage(myQImg.scaled(ui->labView->size(),
Qt::KeepAspectRatio))); //在 Qt 界面上显示图片
}
4.功能实现
图片合成处理功能写在imgProc()方法中,该方法接收1个透明度参数cc,实现代码为:
void MainWindow::imgProc(float alp)
{
Mat imgSrc1 = myImg;
QString imgPath = "shape02.jpg"; //路径中不能含中文字符
Mat imgSrc2 = imread (imgPath.toLatin1().data()) ; //读取图片数据
cvtColor (imgSrc2, imgSrc2, COLOR_BGR2RGB); //图片格式转换
Mat imgDst;
addWeighted(imgSrc2, alp, imgSrc1, 1-alp, 0, imgDst); // (a)
myQImg=QImage((const unsigned char*) (imgDst.data), imgDst.cols, imgDst.rows, QImage::Format_RGB888);
imgShow(); //显示图片
}
其中,
- (a) addWeighted(imgSrc2, alp, imgSrc1, 1-alp, 0, imgDst): OpenCV用addWeighted()方法实现将两张图按照不同的透明度进行叠加,程序写法为:
addWeighted(原图2,a,原图1,1-a,0,合成图);
其中,a为透明度参数,值在0~1.0之间,addWeighted()方法根据给定的两张原图及a值,用插值算法合成一张新图,运算公式为
合成图像素值=原图1像素值 x (1-a)+原图2像素值 x a
特别是,当a=0时,合成图就等同于原图1;当a=1时,合成图等同于原图2。
5.界面事件响应
为使界面上的滑条响应用户操作,当用户拖动或单击滑条时能实时地调整透明度a值,还要编写事件过程代码如下:
void MainWindow::on_verticalSlider_sliderMoved(int position)
{
imgProc(position/100.0);
}
void MainWindow::on_verticalSlider_valueChanged(int value)
{
imgProc(value/100.0);
}
6.运行效果
程序运行后,界面初始显示的是蝴蝶翅膀在上边的动作,如下图(1)所示。
用鼠标向上拖曳滑条可看到背景中逐渐显现蝴蝶翅膀向下的动作,形体动作合成如图(2)-(4)所示。
————————————————
觉得有用的话请关注点赞,谢谢您的支持!
对于本系列文章相关示例完整代码有需要的朋友,可关注并在评论区留言!