Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCv覆盖两个具有透明度的垫子(图形而非图像)_C++_Opencv_Overlays - Fatal编程技术网

C++ OpenCv覆盖两个具有透明度的垫子(图形而非图像)

C++ OpenCv覆盖两个具有透明度的垫子(图形而非图像),c++,opencv,overlays,C++,Opencv,Overlays,嗨,我有两个Mat,我想(按自定义顺序)覆盖它们。Mat保存了一些opencv多边形(这意味着很多透明度)。这个Mat我需要叠加/合并。但不是经典的alpha混合,更像是100%不透明度,而是透明度 这是我想要合并的简单示例代码 Mat m1, m2; m1.create(Point{ 100,100 }, CV_8UC4); m2.create(Point{ 100,100 }, CV_8UC4); cv::polylines(m1, std::vector<Point>{ Po

嗨,我有两个
Mat
,我想(按自定义顺序)覆盖它们。
Mat
保存了一些opencv多边形(这意味着很多透明度)。这个
Mat
我需要叠加/合并。但不是经典的alpha混合,更像是100%不透明度,而是透明度

这是我想要合并的简单示例代码

Mat m1, m2;
m1.create(Point{ 100,100 }, CV_8UC4);
m2.create(Point{ 100,100 }, CV_8UC4);

cv::polylines(m1, std::vector<Point>{ Point{ 2,20 },Point{ 20,40 } }, true, Scalar(6, 6, 255));
cv::polylines(m2, std::vector<Point>{Point{ 100,100 }, Point{ 0,0 } }, true, Scalar(192, 112, 0));
matm1,m2;
m1.创建(点{100100},CV_8UC4);
m2.创建(点{100100},CV_8UC4);
cv::多段线(m1,std::向量{点{2,20},点{20,40},真,标量(6,6255));
cv::多段线(m2,std::向量{Point{100100},Point{0,0},true,标量(192,112,0));
请注意,由于各种原因,我无法在一个
Mat
中直接绘制多边形

我想可能是
m1.copyTo(m2)可以工作,但它会覆盖所有内容(包括黑色背景)


知道如何在没有背景的情况下将其合并/覆盖吗?我可以构造错误的mat吗?

我怀疑您在这些图像中查找黑色时遇到问题,因为它们没有初始化(在调试模式下变得很明显)。如果我们从一个调零矩阵开始,并使用4通道颜色绘制,使线条可见,我们得到如下输入:

投入1:

投入2:

现在,我们可以使用查找设置为(0,0,0,0)的所有像素。因为我们想要一个包含所有非黑色像素的遮罩,所以我们只需要从255中减去它就可以反转。(即
mask=255-mask

遮罩:

最后,使用掩码作为的第二个参数

结果:

代码:


为你想要复制的部分创建一个掩码(我猜所有不是黑色的部分),然后使用
copyTo
与该掩码一起使用。@DanMašek你知道有什么聪明的函数可以检测黑色/除黑色以外的所有部分吗?我尝试了
cv::threshold(m1,m1,1255,cv::THRESH_二进制)但效果不太好。请添加图形的示例图像。
#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat m1(100, 100, CV_8UC4, cv::Scalar(0, 0, 0, 0));
    cv::Mat m2(100, 100, CV_8UC4, cv::Scalar(0, 0, 0, 0));

    cv::polylines(m1
        , std::vector<cv::Point>{cv::Point{2, 20}, cv::Point{20, 40}}
        , true, cv::Scalar(6, 6, 255, 255));
    cv::polylines(m2
        , std::vector<cv::Point>{cv::Point{100, 100}, cv::Point{0, 0}}
        , true, cv::Scalar(192, 112, 0, 255));

    cv::Mat mask;
    cv::inRange(m2, cv::Scalar(0, 0, 0, 0), cv::Scalar(0, 0, 0, 0), mask);
    mask = 255 - mask; // invert the mask

    cv::Mat result(m1.clone());
    m2.copyTo(result, mask);

    cv::imwrite("transp_in_1.png", m1);
    cv::imwrite("transp_in_2.png", m2);
    cv::imwrite("transp_mask.png", mask);
    cv::imwrite("transp_res.png", result);

    return 0;
}
cv::Mat mask;
cv::inRange(m2, cv::Scalar(0, 0, 0, 0), cv::Scalar(0, 0, 0, 0), mask);

cv::Mat result(m2.clone());
m1.copyTo(result, mask);