2017-07-16 9 views
1

こんにちは私は(カスタム注文でオーバレイしたい)Matです。 Matには、いくつかのopencvポリゴンが保持されています(透明度が高いことを意味します)。このMat私はオーバーレイ/マージする必要があります。しかし、古典的なアルファブレンドでは100%の不透明度に似ていますが、透明性はありません。OpenCv overlay 2つのMat(図面ではなく画像)の透明度

これは私がマージしたいものの簡単なサンプルコードです。

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

私は様々な理由により1 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

今、我々は、(0,0,0,0)に設定されているすべてのピクセルを見つけるためにinRangeを使用することができます。我々は、すべての非黒画素のマスクをしたいので、私たちは255から減算することによって、それを反転(すなわちmask = 255 - mask

マスク:

Mask

最後に、の2番目のパラメータとしてマスクを使用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; 
} 

代わりにマスクを反転させる、あなたがコピーしている方向を反転させることができます。 (すなわちm1からのものでm2に黒のすべてを上書き)

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); 
関連する問題