opencv图片线性融合addWeighted及Qt显示Mat数据

引言

上一篇博客介绍了highGUI的一些知识,也用到了线性融合的例子,这里把线性融合作为单独的例子拿出来讲一下,并介绍下Mat数据在Qt的渲染过程。

图片线性融合

理论公式:在这里插入图片描述
g(x)表示输出的融合像素,α是alpha系数0-1取值范围。f0和f1是背景和前景像素

函数原型:
void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);
参数说明:
src1:输入图形1
alpha:src1的alpha系数
src2:输入图形2
beta:src2的alpha系数
gamma:gamma系数
dst:输出图象

1.读取图片融合

注意:2张融合的图片大小类型需要一致。

 	//读取图片1
    cv::Mat image1 = cv::imread("F:/work/opencv/linearblending/add.jpg");
    if(image1.empty())
    {
    
    
        qDebug("cv read image1 falied!");
        return;
    }
    //读取图片2
    cv::Mat image2 = cv::imread("F:/work/opencv/linearblending/timg.jpg");
    if(image2.empty())
    {
    
    
        qDebug("cv read image2 falied!");
        return;
    }

    cv::Mat imageROI;
    //将图1与图2线性混合
    addWeighted(image1,0.6,image2,0.9,0,imageROI);

    //显示图片
    bgrMat2Image(imageROI);;

2.mat转QImage

void LinearBlending::bgrMat2Image(cv::Mat mat)
{
    
    
    if(mat.channels() == 3)
    {
    
    
        qDebug("bgrMat2Image channel 3");
        cv::cvtColor(mat, mat, CV_BGR2RGB);
        mImage = QImage((const uchar*)(mat.data),mat.cols,mat.rows,QImage::Format_RGB888);
    }
    else if(mat.channels() == 4)
    {
    
    
        cv::cvtColor(mat, mat, CV_BGRA2RGBA);
        mImage = QImage((const uchar*)(mat.data),mat.cols,mat.rows,mat.cols*mat.channels(),QImage::Format_ARGB32);
    }
    else
    {
    
    
        //gray
        cv::cvtColor(mat, mat, CV_GRAY2RGB);
        mImage = QImage((const uchar*)mat.data,mat.cols,mat.rows,QImage::Format_Indexed8);
    }
    //mImage.scanLine(0);
    mImage.bits();

    this->update();
}

3.QPainter显示

void LinearBlending::paintEvent(QPaintEvent *event)
{
    
    
    Q_UNUSED(event)

    QPainter painter(this);
    if(mImage.isNull())
    {
    
    
        qDebug("paintEvent image is null");
        return;
    }
    painter.drawImage(0,0,mImage);
}

当然了,也可把QImage数据再转成QPixmap放到QLabel中显示。

4.效果展示

图片1:
在这里插入图片描述
图片2:
在这里插入图片描述
融合后效果:
在这里插入图片描述

感兴趣区域融合ROI

    //读取图片1
    cv::Mat image1 = cv::imread("F:/work/opencv/linearblending/add.jpg");
    if(image1.empty())
    {
    
    
        qDebug("cv read image1 falied!");
        return;
    }
    //读取图片2
    cv::Mat image2 = cv::imread("F:/work/opencv/linearblending/timo.jpg");
    if(image2.empty())
    {
    
    
        qDebug("cv read image2 falied!");
        return;
    }
    //选取感兴趣区域
    cv::Mat imageROI = image1(Rect(240,100,image2.cols,image2.rows));
    //将图1与图2线性混合
    addWeighted(imageROI,0.4,image2,0.8,0,imageROI);
    //显示图片
    bgrMat2Image(image1);

效果如下:
在这里插入图片描述
最终把timo图片融合到背景图感兴趣的区域。

作者:费码程序猿
欢迎技术交流:QQ:255895056
转载请注明出处,如有不当欢迎指正

猜你喜欢

转载自blog.csdn.net/haohaohaihuai/article/details/106228733