如何在OpenCV中使用蒙版混合图像?

时间:2016-12-21 12:38:35

标签: opencv

我有img1img2两种类型CV_8UC3mask类型CV_8UC1的图片。

所有矩阵的值都在0-255范围内。我想计算结果:

mask_ .* img1 + (1.0 - mask_) * img2

其中mask_ = mask / 255.0

如何正确执行此操作?如果我需要中间mask_,它的类型/声明是什么?

2 个答案:

答案 0 :(得分:0)

在找到内置方法之前,我会使用以下内容:

cv::Mat weightedBlend(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &mask) {
    assert((img1.type() == CV_8UC1 && img2.type() == CV_8UC1) ||
           (img1.type() == CV_8UC3 && img2.type() == CV_8UC3));
    assert(mask.type() == CV_8UC1);
    assert(img1.rows == mask.rows && img1.cols == mask.cols);
    assert(img2.rows == mask.rows && img2.cols == mask.cols);

    cv::Mat res(img1.rows, img1.cols, img1.type());
    const int nChannels = img1.channels();

    for (int iRow = 0; iRow < mask.rows; ++iRow) {
        const uchar *pImg1Row = img1.ptr<uchar>(iRow);
        const uchar *pImg2Row = img2.ptr<uchar>(iRow);
        const uchar *pMaskRow = mask.ptr<uchar>(iRow);
        uchar *pResRow = res.ptr<uchar>(iRow);

        for (int iCol = 0; iCol < mask.cols; ++iCol) {
            float w = pMaskRow[iCol] / 255.0;
            for (int iChan = 0; iChan < nChannels; ++iChan) {
                int iChanElem = nChannels * iCol + iChan;
                pResRow[iChanElem] = roundf(w * pImg1Row[iChanElem] + (1-w) * pImg2Row[iChanElem]);
            }
        }
    }

    return res;
}

答案 1 :(得分:-1)

您可以将img1的内容复制到img2,并提供一个掩码,仅复制掩码所涵盖的区域:

img1.copyTo(img2, mask);

之后img2包含img1img2

之间的混合