如何在OpenCV中使用遮罩混合图像?

如何在OpenCV中使用遮罩混合图像?,opencv,Opencv,我有两张CV_8UC3类型的img1和img2图像,还有一张CV_8UC1类型的mask 所有矩阵的值都在0-255范围内。我想计算以下结果: mask_ .* img1 + (1.0 - mask_) * img2 其中mask\uu=mask/255.0 如何正确地做到这一点?如果我需要中间掩码,它的类型/声明是什么?您可以将img1的内容复制到img2并提供一个掩码,以便仅复制掩码覆盖的区域: img1.copyTo(img2, mask); 之后,img2包含img1和img2之间的

我有两张
CV_8UC3
类型的
img1
img2
图像,还有一张
CV_8UC1
类型的
mask

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

mask_ .* img1 + (1.0 - mask_) * img2
其中
mask\uu=mask/255.0


如何正确地做到这一点?如果我需要中间
掩码
,它的类型/声明是什么?

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

img1.copyTo(img2, mask);

之后,
img2
包含
img1
img2
之间的混合,您可以将
img1
的内容复制到
img2
并提供一个掩码,以便仅复制掩码所覆盖的区域:

img1.copyTo(img2, mask);

之后,
img2
包含了
img1
img2
之间的混合,直到我找到了一种内置的方法来实现这一点,以下是我使用的:

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;
}
cv::Mat-weightedBlend(常数cv::Mat&img1,常数cv::Mat&img2,常数cv::Mat&mask){
断言((img1.type()==CV_8UC1&&img2.type()==CV_8UC1)||
(img1.type();
断言(mask.type()==CV_8UC1);
断言(img1.rows==mask.rows&&img1.cols==mask.cols);
断言(img2.rows==mask.rows&&img2.cols==mask.cols);
cv::Mat res(img1.rows、img1.cols、img1.type());
const int nChannels=img1.channels();
对于(int-iRow=0;iRow
在我找到一种内置的方法之前,以下是我使用的方法:

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;
}
cv::Mat-weightedBlend(常数cv::Mat&img1,常数cv::Mat&img2,常数cv::Mat&mask){
断言((img1.type()==CV_8UC1&&img2.type()==CV_8UC1)||
(img1.type();
断言(mask.type()==CV_8UC1);
断言(img1.rows==mask.rows&&img1.cols==mask.cols);
断言(img2.rows==mask.rows&&img2.cols==mask.cols);
cv::Mat res(img1.rows、img1.cols、img1.type());
const int nChannels=img1.channels();
对于(int-iRow=0;iRow
您可以使用Opencv的filter2D和addweight函数。
mask_uu2;.mul(img1)+(1.0-mask_2;).mul(img2)如何声明掩码;mask.converTo(mask_u、CV_32F、1.0/255.0
。然后可能需要分别混合每个通道(请参见
CV::split
CV::merge
)每个通道必须单独计算,可能img1和img2也必须是CV_32F格式。我会在循环中手动计算每像素混合。您可以使用Opencv的filter2D和addweight函数。
mask_uu2;.mul(img1)+(1.0-mask_2;.mul(img2);
如何声明mask_2;
Mat mask_2;;mask.converTo(掩码、CV、32F、1.0/255.0
。然后可能需要分别混合每个通道(请参见
CV::split
CV::merge
)每个通道必须单独计算,可能img1和img2也必须是CV_32F格式。我会在循环中手动计算每像素混合。但是这里的掩码是二进制的,它将处理相同的1和255值(即,仅当掩码像素为零或非零时才重要),但是这里的掩码是二进制的,它将处理相同的1和255值(即,仅当遮罩像素为零或非零时才起作用)