ある画像に図形を描画をし、既に描画された所には描画しないような処理をしたいのですが、どのようにすれば良いでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
(タグにOpenCV
がついてるので…)
マスクを用意し,cv::Mat::copyTo
で使う.
原理確認のサンプルコードを示す.
C++
1class TestClass 2{ 3public: 4 TestClass( int ImgW, int ImgH ) 5 { 6 m_MasterImg = cv::Mat::zeros( ImgH, ImgW, CV_8UC3 ); 7 m_TempCanvas = cv::Mat::zeros( m_MasterImg.size(), CV_8UC3 ); 8 m_Mask = cv::Mat( m_MasterImg.size(), CV_8UC1 ); 9 m_Mask = 255; 10 } 11 12public: 13 const cv::Mat &CurrImg() const { return m_MasterImg; } 14 15 void DrawCircle( cv::Point Center, int Radius, cv::Scalar Color, int Thickness ) 16 { 17 cv::circle( m_TempCanvas, Center, Radius, Color, Thickness ); 18 m_TempCanvas.copyTo( m_MasterImg, m_Mask ); 19 cv::circle( m_Mask, Center, Radius, cv::Scalar(0), Thickness ); 20 } 21 22private: 23 cv::Mat m_MasterImg; 24 cv::Mat m_Mask; 25 cv::Mat m_TempCanvas; 26}; 27 28 29int main() 30{ 31 TestClass Test( 320, 240 ); 32 //赤,緑,青 の順で描画 33 Test.DrawCircle( cv::Point(100,100), 60, cv::Scalar(0,0,255), -1 ); 34 Test.DrawCircle( cv::Point(150,120), 50, cv::Scalar(0,255,0), 5 ); 35 Test.DrawCircle( cv::Point(230,150), 100, cv::Scalar(255,32,32), 8 ); 36 37 cv::imshow( "Result", Test.CurrImg() ); 38 if( cv::waitKey() == 's' ){ cv::imwrite( "Result.png", Test.CurrImg() ); } 39 return 0; 40}
投稿2021/01/21 04:03
編集2021/01/22 09:43総合スコア11985
0
ベストアンサー
考え方
描画済みかどうかを管理するための2値画像を作成しておけばいいと思います。
描画済みの場合は255、描画されてない場合は0、最初はまだなにも描画されていないので0で初期化
なにか図形を描画するときに
- 画像のコピーを作成して、それに対して描画する
- 画素単位で描画済みかどうかのフラグを参照し、0 (まだなにも描画されていない) 場合はもとの画像に描画結果を反映する
- 描画が済みかどうかのフラグを管理する画像も同じ描画関数を使って更新する
とすればいいと思います。
以下 Python のコードですが、C++ でもやり方は同じです。
OpenCV C++API の場合の関数
- np.zeros() → cv::Mat::zeros(height, width, CV_8UC1): 0で初期化したマスク画像を作成する
- np.where() → copyTo(img, mask): mask の値が255の画素だけコピーする
python
1import cv2 2import numpy as np 3 4width, height = 500, 500 5 6img = np.full((width, height, 3), 255, np.uint8) 7is_drawn = np.zeros((width, height), np.uint8) 8 9# 別の画像に文字描画 10# is_drawn で0の画素 (まだ何も描画されていない) の場合、描画結果を反映する 11new_img = cv2.rectangle( 12 img.copy(), (50, 50), (250, 250), color=(255, 0, 0), thickness=-1 13) 14# is_drawn が255の画素 (すでに何かが描画されてる) の場合、描画結果は反映しない 15img = np.where(is_drawn[..., np.newaxis] == 0, new_img, img) 16 17# 今回描画した画素は is_drawn の画素を255にして更新 18cv2.rectangle(is_drawn, (50, 50), (250, 250), color=255, thickness=-1) 19 20# 長方形描画 21new_img = cv2.circle(img.copy(), (50, 50), 300, color=(255, 0, 255), thickness=-1) 22img = np.where(is_drawn[..., np.newaxis] == 0, new_img, img) 23cv2.circle(is_drawn, (50, 50), 300, color=255, thickness=-1)
投稿2021/01/21 04:02
編集2021/01/21 04:10総合スコア21956
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答ありがとうございます。
描画対象の元画像は白単色の物でなくとも大丈夫ですか?(普通の写真など)
2021/01/22 09:41
> 元画像は白単色の物でなくとも大丈夫ですか?
描画する画像はなんでも大丈夫です
2021/01/22 10:25
ありがとうございます.
思うような結果が出せました.
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/22 12:31