質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Q&A

解決済

2回答

1611閲覧

画像への描画されない処理

prog_tamaza

総合スコア14

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

0グッド

0クリップ

投稿2021/01/21 03:43

編集2021/01/23 04:21

ある画像に図形を描画をし、既に描画された所には描画しないような処理をしたいのですが、どのようにすれば良いでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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
fana

総合スコア11708

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/01/22 12:31

(わざわざ質問編集で言語が指定されたから,既存の回答じゃ不足なのか?と思いコードを追加したが,全然求められてなかったぜ!)
guest

0

ベストアンサー

考え方

描画済みかどうかを管理するための2値画像を作成しておけばいいと思います。
描画済みの場合は255、描画されてない場合は0、最初はまだなにも描画されていないので0で初期化

なにか図形を描画するときに

  1. 画像のコピーを作成して、それに対して描画する
  2. 画素単位で描画済みかどうかのフラグを参照し、0 (まだなにも描画されていない) 場合はもとの画像に描画結果を反映する
  3. 描画が済みかどうかのフラグを管理する画像も同じ描画関数を使って更新する

とすればいいと思います。

以下 Python のコードですが、C++ でもやり方は同じです。

OpenCV C++API の場合の関数

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
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

prog_tamaza

2021/01/22 09:26

回答ありがとうございます。 描画対象の元画像は白単色の物でなくとも大丈夫ですか?(普通の写真など)
tiitoi

2021/01/22 09:41

> 元画像は白単色の物でなくとも大丈夫ですか? 描画する画像はなんでも大丈夫です
prog_tamaza

2021/01/22 10:25

ありがとうございます. 思うような結果が出せました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問