c++qt合并两张灰度图像

发布于:2024-06-14 ⋅ 阅读:(63) ⋅ 点赞:(0)

需求:将两张尺寸相同的灰度图像进行合并,合并后的图像,每个像素点灰度值为两张原图对应像素点灰度值之和。若超过255,则最大为255。


方法一:
将图像读取为cv::Mat,再调用opencv的cv::add方法,进行合并。

方法二:
不调用opencv的方法。假设两个图像数数据都为void 指针,先将其都转为unsigned char 指针,再按下标进行相加,并处理溢出情况。用一个新的unsigned char指针接收,最后再转回void指针。


配置opencv方法可参考以下文章:
https://blog.csdn.net/bangtanhui/article/details/135583311


效果如下:
两张一样的原图,合并后得到一张整体灰度值更高(更亮)的图。

在这里插入图片描述
在这里插入图片描述

参考代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"

//该函数用于将cv::Mat转为QImage
QImage cvMat2QImage(const cv::Mat& mat)
{
    // 8-bits unsigned, NO. OF CHANNELS = 1
    if(mat.type() == CV_8UC1) {
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        // Set the color table (used to translate colour indexes to qRgb values)
        image.setColorCount(256);
        for(int i = 0; i < 256; i++) {
            image.setColor(i, qRgb(i, i, i));
        }
        // Copy input Mat
        uchar *pSrc = mat.data;
        for(int row = 0; row < mat.rows; row ++) {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, static_cast<size_t>(mat.cols));
            pSrc += mat.step;
        }
        return image;
    } else if(mat.type() == CV_8UC3) {      // 8-bits unsigned, NO. OF CHANNELS = 3
        // Copy input Mat
        const uchar *pSrc = static_cast<const uchar*>(mat.data);
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_RGB888);
        return image.rgbSwapped();
    } else if(mat.type() == CV_8UC4) {
        // Copy input Mat
        const uchar *pSrc = static_cast<const uchar*>(mat.data);
        // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_ARGB32);
        return image.copy();
    } else {
        return QImage();
    }
}


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    QString imgPath1 = "E:\\QtDemo\\ImageMerge_Demo\\img_test.bmp";
    QString imgPath2 = "E:\\QtDemo\\ImageMerge_Demo\\img_test_append.bmp";


    cv::Mat imgMat1 = cv::imread(imgPath1.toStdString(), CV_8UC1);
    cv::Mat imgMat2 = cv::imread(imgPath2.toStdString(), CV_8UC1);

#if 0
    //方法一
    cv::Mat addImgMat;
    
    //两个图像尺寸需要相同,不然会出错
    //该方法不需要考虑超过255的情况
    cv::add(imgMat1, imgMat2, addImgMat);

    QImage addImage = cvMat2QImage(addImgMat);
    addImage.save("add.bmp");

#else

    //方法二
    void* dataPtr1 = static_cast<void*>(imgMat1.data);
    void* dataPtr2 = static_cast<void*>(imgMat2.data);

    unsigned char* imgData1 = static_cast<unsigned char*>(dataPtr1);
    unsigned char* imgData2 = static_cast<unsigned char*>(dataPtr2);

    unsigned char *Data = new unsigned char[8192*4000];
    for(int i=0; i<8192*4000; i++)
    {
        unsigned short sum = imgData1[i] + imgData2[i];
        Data[i] = sum > 255 ? 255 : sum;
    }
    void* voidPtr = static_cast<void*>(Data);

    cv::Mat addMat = cv::Mat(static_cast<int>(4000), static_cast<int>(8192), CV_8UC1, voidPtr);
    QImage addImg = cvMat2QImage(addMat);
    addImg.save("add2.bmp");

#endif

}

MainWindow::~MainWindow()
{
    delete ui;
}