QT+opencv ROI区域图像叠加&初级图像混合 label里输出Mat图片要做的变换

来源:互联网 发布:用户画像的数据来源 编辑:程序博客网 时间:2024/06/06 01:16

虽然使用opencv大多不使用ui,但是这次输出的图像用来对比比较有意义,我为了让他们输出在界面上好看一些,弄了一下午,达到如下效果。

这里写图片描述

1.

先说一下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());

2.

    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 <QCoreApplication>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <qdebug.h>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界面版

UI输出源代码

3个文件
- mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QApplication>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <qdebug.h>#include <qlabel.h>using namespace cv;using namespace std;namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{    Q_OBJECTpublic:    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
  • mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <qdebug.h>#include <qlabel.h>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;}
  • main.cpp
#include "mainwindow.h"#include <QApplication>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <qdebug.h>#include <qlabel.h>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界面版

阅读全文
1 0
原创粉丝点击