2017-07-16 79 views
1

嗨,我有几个Mat,我想重叠(以自定义顺序)。 Mat holdes一些opencv多边形(这意味着很多透明度)。这Mat我需要覆盖/合并。但与传统的阿尔法混合更像是100%不透明但具有透明度。OpenCv覆盖两个垫(图纸不是图像)与透明度

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

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)); 

请注意,我不能在一个Mat直接绘制多边形由于种种原因。

我想,也许m1.copyTo(m2);会的工作,但其覆盖的一切(包括黑色背景)

不知道如何得到它合并了/没有背景重叠?我可以构造垫子的错吗?

+2

创建要复制(我猜的一切,这不是黑色)件的面罩,然后用'copyTo'与面具。 –

+0

@DanMašek你知道任何聪明的功能来检测黑色/黑色以外的所有东西吗?我试过cv :: threshold(m1,m1,1,255,cv :: THRESH_BINARY);'但是它的工作不太好。 – user1234

+1

添加图纸的示例图像。 – Micka

回答

2

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

输入1:

Input 1

输入2 :现在

Input 2

,我们可以使用inRange找到设置为(0,0,0,0)的所有像素。因为我们希望所有非黑色像素的面具,我们只是通过从255减去它反转(即mask = 255 - mask

面膜:

Mask

最后,使用面具作为第二个参数copyTo

结果:

Result

代码:

#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; 
} 

而是反转的面具,可以颠倒在复制的方向。 (即覆盖所有黑色m2有东西从m1

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);