虽然使用opencv大多不使用ui,但是这次输出的图像用来对比比较有意义,我为了让他们输出在界面上好看一些,弄了一下午,达到如下效果。
先说一下QT label中输出opencv Mat图像的事情:
因为使用Imread读入的Mat图像,其矩阵格式是BGR的,我们在label上输出只能使用QT自带的比如QPixmap函数,此时就要对Mat图像进行转化。
主要就3行代码,如下 srcImage4就是用imread读入的图像,或者你经过各种其他处理之后的Mat型的数据就行。先使用cvtColor把BGR颜色空间换成QImage图像的RGB颜色空间,用QImage读入数据,在label上输出就行。
后两句代码是对label中输出图像的设置,可以使图像按照label大小直接输出。
Mat srcImage4 = imread("girl.jpg");
QImage img4;
cvtColor(srcImage4,srcImage4,CV_BGR2RGB);
img4=QImage((const unsigned char*)(srcImage4.data),
srcImage4.cols,srcImage4.rows,QImage::Format_RGB888);
ui->label_4->setScaledContents(true);
ui->label_4->resize(ui->label->width(),ui->label->height());
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1);
第一个参数,InputArray类型的src1,表示需要加权的第一个数组,常常填一个Mat。
第二个参数,alpha,表示第一个数组的权重
第三个参数,src2,表示第二个数组,它需要和第一个数组拥有相同的尺寸和通道数。
第四个参数,beta,表示第二个数组的权重值。
第五个参数,dst,输出的数组,它和输入的两个数组拥有相同的尺寸和通道数。
第六个参数,gamma,一个加到权重总和上的标量值。看下面的式子自然会理解。
第七个参数,dtype,输出阵列的可选深度,有默认值-1。;当两个输入数组具有相同的深度时,这个参数设置为-1(默认值),即等同于src1.depth()。
简单来说,就是把Mat类型的图片src1和src2以alpha:beta的比例加在一起显示出来。
如果用数学公式来表达,addWeighted函数计算如下两个数组(src1和src2)的加权和,得到结果输出给第四个参数。即addWeighted函数的作用可以被表示为为如下的矩阵表达式为:
dst = src1[I]*alpha+ src2[I]*beta + gamma;
其中的I,是多维数组元素的索引值。而且,在遇到多通道数组的时候,每个通道都需要独立地进行处理。另外需要注意的是,当输出数组的深度为CV_32S时,这个函数就不适用了,这时候就会内存溢出或者算出的结果压根不对。
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
//-----------------------------------【全局函数声明部分】--------------------------------------
// 描述:全局函数声明
//-----------------------------------------------------------------------------------------------
bool ROI_AddImage();
bool LinearBlending();
bool ROI_LinearBlending();
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main( )
{
if(ROI_AddImage( )&& LinearBlending( )&&ROI_LinearBlending( ))
{
qDebug() << QString::fromLocal8Bit("输出貌似成功了!");
}
waitKey(0);
return 0;
}
//----------------------------------【ROI_AddImage( )函数】----------------------------------
// 函数名:ROI_AddImage()
// 描述:利用感兴趣区域ROI实现图像叠加
//----------------------------------------------------------------------------------------------
bool ROI_AddImage()
{
// 【1】读入图像
Mat srcImage1= imread("dota_pa.jpg");
Mat logoImage= imread("dota_logo.jpg");
if( !srcImage1.data ) { printf(" 读取srcImage1错误~! \n"); return false; }
if( !logoImage.data ) { printf(" 读取logoImage错误~! \n"); return false; }
// 【2】定义一个Mat类型并给其设定ROI区域
Mat imageROI= srcImage1(Rect(200,250,logoImage.cols,logoImage.rows));
// 【3】加载掩模(必须是灰度图)
Mat mask= imread("dota_logo.jpg",0);
//【4】将掩膜拷贝到ROI
logoImage.copyTo(imageROI,mask);
// 【5】显示结果
namedWindow("<1>利用ROI实现图像叠加示例窗口",WINDOW_NORMAL);
imshow("<1>利用ROI实现图像叠加示例窗口",srcImage1);
return true;
}
//---------------------------------【LinearBlending()函数】-------------------------------------
// 函数名:LinearBlending()
// 描述:利用cv::addWeighted()函数实现图像线性混合
//--------------------------------------------------------------------------------------------
bool LinearBlending()
{
//【0】定义一些局部变量
double alphaValue = 0.5;
double betaValue;
Mat srcImage2, srcImage3, dstImage;
// 【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )
srcImage2 = imread("mogu.jpg");
srcImage3 = imread("rain.jpg");
if( !srcImage2.data ) { printf(" 读取srcImage2错误~! \n"); return false; }
if( !srcImage3.data ) { printf(" 读取srcImage3错误~! \n"); return false; }
// 【2】进行图像混合加权操作
betaValue = ( 1.0 - alphaValue );
addWeighted( srcImage2, alphaValue, srcImage3, betaValue, 0.0, dstImage);
// 【3】创建并显示原图窗口
namedWindow("<2>线性混合示例窗口【原图】 ", WINDOW_NORMAL);
imshow( "<2>线性混合示例窗口【原图】 ", srcImage2 );
namedWindow("<3>线性混合示例窗口【效果图】 ", WINDOW_NORMAL);
imshow( "<3>线性混合示例窗口【效果图】 ", dstImage );
return true;
}
//---------------------------------【ROI_LinearBlending()】-------------------------------------
// 函数名:ROI_LinearBlending()
// 描述:线性混合实现函数,指定区域线性图像混合.利用cv::addWeighted()函数结合定义
// 感兴趣区域ROI,实现自定义区域的线性混合
//--------------------------------------------------------------------------------------------
bool ROI_LinearBlending()
{
//【1】读取图像
Mat srcImage4= imread("dota_pa.jpg",1);
Mat logoImage= imread("dota_logo.jpg");
if( !srcImage4.data ) { printf(" 读取srcImage4错误~! \n"); return false; }
if( !logoImage.data ) { printf(" 读取logoImage错误~! \n"); return false; }
//【2】定义一个Mat类型并给其设定ROI区域
Mat imageROI;
//方法一
imageROI= srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));
//方法二
//imageROI= srcImage4(Range(250,250+logoImage.rows),Range(200,200+logoImage.cols));
//【3】将logo加到原图上
addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);
//【4】显示结果
namedWindow("<4>区域线性图像混合示例窗口 " ,WINDOW_NORMAL);
imshow("<4>区域线性图像混合示例窗口 ",srcImage4);
return true;
}
MIX1 无ui界面版
3个文件
- mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
Mat srcImage1;
Mat logoImage;
Mat imageROI;
Mat mask;
Mat srcImage2, srcImage3, dstImage;
Mat srcImage4;
QImage img1,img2,img2_1,img2_2,img4;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
srcImage1= imread("dota_pa.jpg");
logoImage= imread("dota_logo.jpg");
// 【2】定义一个Mat类型并给其设定ROI区域
imageROI= srcImage1(Rect(200,250,logoImage.cols,logoImage.rows));
// 【3】加载掩模(必须是灰度图)
mask= imread("dota_logo.jpg",0);
//【4】将掩膜拷贝到ROI
logoImage.copyTo(imageROI,mask);
cvtColor(srcImage1,srcImage1,CV_BGR2RGB);
img1=QImage((const unsigned char*)(srcImage1.data),srcImage1.cols,srcImage1.rows,QImage::Format_RGB888);
ui->label->setPixmap(QPixmap::fromImage(img1));
ui->label->setScaledContents(true);
ui->label->resize(ui->label->width(),ui->label->height());
//ui->label->resize(ui->label->pixmap()->size());
// 【1】读取图像 ( 两幅图片需为同样的类型和尺寸 )
srcImage2 = imread("mogu.jpg");
srcImage3 = imread("rain.jpg");
// 【2】进行图像混合加权操作
addWeighted( srcImage2, 0.5, srcImage3, 0.5, 0.0, dstImage);
cvtColor(dstImage,dstImage,CV_BGR2RGB);
img2=QImage((const unsigned char*)(dstImage.data),dstImage.cols,dstImage.rows,QImage::Format_RGB888);
ui->label_2->setPixmap(QPixmap::fromImage(img2));
ui->label_2->setScaledContents(true);
ui->label_2->resize(ui->label->width(),ui->label->height());
cvtColor(srcImage2,srcImage2,CV_BGR2RGB);
img2_1=QImage((const unsigned char*)(srcImage2.data),srcImage2.cols,srcImage2.rows,QImage::Format_RGB888);
ui->label_3->setPixmap(QPixmap::fromImage(img2_1));
ui->label_3->setScaledContents(true);
ui->label_3->resize(ui->label->width(),ui->label->height());
cvtColor(srcImage3,srcImage3,CV_BGR2RGB);
img2_2=QImage((const unsigned char*)(srcImage3.data),srcImage3.cols,srcImage3.rows,QImage::Format_RGB888);
ui->label_5->setPixmap(QPixmap::fromImage(img2_2));
ui->label_5->setScaledContents(true);
ui->label_5->resize(ui->label->width(),ui->label->height());
srcImage4= imread("dota_pa.jpg",1);
logoImage= imread("dota_logo.jpg");
//方法一
imageROI= srcImage4(Rect(200,250,logoImage.cols,logoImage.rows));
//【3】将logo加到原图上
addWeighted(imageROI,0.5,logoImage,0.3,0.,imageROI);
cvtColor(srcImage4,srcImage4,CV_BGR2RGB);
img4=QImage((const unsigned char*)(srcImage4.data),srcImage4.cols,srcImage4.rows,QImage::Format_RGB888);
ui->label_4->setPixmap(QPixmap::fromImage(img4));
ui->label_4->setScaledContents(true);
ui->label_4->resize(ui->label->width(),ui->label->height());
}
MainWindow::~MainWindow()
{
delete ui;
}
#include "mainwindow.h"
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
qDebug() << QString::fromLocal8Bit("输出貌似成功了!");
waitKey(0);
return a.exec();
}
MIX2 ui界面版