2017-07-16 118 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);