質問するログイン新規登録
OpenCV

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1061閲覧

opencv python 画像を多角形で切り抜きたい

zen434272

総合スコア0

OpenCV

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2024/01/25 11:41

0

0

現在uebカメラ4つで自動車についているパノラミックモニターを制作しようとしています。
opencv pythonで映像を多角形に切り出して背景の画像に合成したいです。
ポリゴンのマスクを作るなど試しましたがイマイチ分からず、切り出した多角形の周りが黒くなってしまい後ろの映像が見えなくなってしまうのも避けたいので、マスクで切り出して切り出した場所以外は透過するように作りたいです。
知識のある方よろしくお願いします。

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

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

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

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

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

fana

2024/01/26 00:06

この文章だけを読むかぎりでは, マスクを作ることまでができるのであれば,それを用いて「背景画像の上に,カメラ画像(?)のうちのマスク領域だけをコピーする」という処理をすれば良いだけ ……な話であるように読めるのですが,何が問題なのですか? (そもそも それが可能だから マスクを作った のですよね? 用途不明な段階でなんとなくマスクを作るという行為に向かうわけはないでしょうから)
can110

2024/01/26 01:40

どんな回答を求めていますか?
zen434272

2024/01/26 04:16

https://www.web-dev-qa-db-ja.com/ja/python/opencv%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E7%94%BB%E5%83%8F%E3%81%8B%E3%82%89%E5%87%B9%E5%A4%9A%E8%A7%92%E5%BD%A2%E3%82%92%E3%83%88%E3%83%AA%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8Bpython/836552106/ このサイトを元に座標指定でしたい形にして出力まではいけました。 しかし、そこから画像をペーストで重ねると切り抜いた場所以外の外側が黒くなってしまい下の画像が見えなくなってしまっていて、その黒い部分を透明化して下の画像を見えるようにしたいです。 使えそうなソースやマスク領域だけのコピーの仕方など教えていただきたいです。
fana

2024/01/26 04:45 編集

> 切り抜いた場所以外の外側が黒くなってしまい そのリンク先でも「白い背景」を実現しているように見えるのですが…? それと「同じような」処理(:白い背景に重ねるためのコードを単に丸ごとコピペするのじゃなくて)を考えるのはダメなのですか?(っていうのを回答にも書きましたけど)
zen434272

2024/01/26 10:43

>「同じような」処理(:白い背景に重ねるためのコードを単に丸ごとコピペするのじゃなくて)を考えるのはダメなのですか? それがわからなかったため投稿しました。
zen434272

2024/01/26 11:06

白い背景だと後ろの画像が見えるようになるのですか?
fana

2024/01/27 03:01 編集

たまたま全体が真っ白い絵があったとして → そこにコピーしたくない範囲が「透明」であるかのようなコピー処理をしたならば → 結果はそこだけ白い「背景」が残るよね っていう話自体がもう飲み込めない感じですか? これの「全体が真っ白い絵」というのが別の画像(あなたの言う「下の画像」)だとしても同様にやれば全く同じ話になると思うのですが. 正直,ここまでのやりとりを見るに,私があなたの質問文から読み取っている「こういうことがしたいのだろう」という理解の側が間違っているのか? という気すらしてきました. (「何のためにどう用いるのか不明なマスクだけは作った」という現状も理解できませんし,ひょっとしたらその「マスク」というのはこちらの想像しているものとは全く異なるのかもしれません.) 現状の回答では解決しないのであれば,他者の回答を待ってください. (互いに「何言ってるのかわからない」この状態を解消できるような気がしませんので)
zen434272

2024/01/27 08:32

了解しました。
guest

回答1

0

OpenCV なら Mat クラスに copyTo というメソッドがあると思うのですが, Python からだと使えない感じなんですか?
(私は Python から OpenCV 使ったことないので,そこらへんの事情とかわかりませんが)

仮に上記が使えないのだとしても,あなたが示した参考先を見た感じだと bitwise_and とかは普通に使えるのでしょうから,そういうのを用いて都合が良い処理を組み立てるのではダメなのですか?
Wikipedia でも説明あるみたいですが.


[追記]
とりあえず copyTo のサンプルを示しておく.C++だが.

※やりたいことは単にこういう話ではないのか? と読んだのだが,違うのだろうか?
違うならば,他者からの的確な回答を得るためにはその旨が明確になるよう質問文の内容を考えた方が良いのでは.

C++

1int main() 2{ 3 //背景画像 4 cv::Mat BkImg( 200, 160, CV_8UC3 ); 5 for( int x=0; x<BkImg.cols; ++x ) 6 {//※真っ白とかだと話が分かり難い様子なので,適当な模様を描画しておく 7 unsigned char R = (unsigned char)( 128 + 120 * cos( x*0.05 ) ); 8 unsigned char B = 255 - R; 9 cv::line( BkImg, cv::Point(x,0), cv::Point(x,BkImg.rows), cv::Scalar(B,0,R) ); 10 } 11 cv::imshow( "BkImg", BkImg ); 12 13 //前景画像 14 cv::Mat ForeImg( 120, 100, CV_8UC3 ); 15 for( int y=0; y<ForeImg.rows; ++y ) 16 {//※適当に背景とは異なる模様を描画している 17 unsigned char G = (unsigned char)( 128 + 120 * cos( y*0.1 ) ); 18 unsigned char R = 255 - G; 19 unsigned char B = R / 2; 20 cv::line( ForeImg, cv::Point(0,y), cv::Point(ForeImg.cols,y), cv::Scalar(B,G,R) ); 21 } 22 cv::imshow( "ForeImg", ForeImg ); 23 24 //マスク.前景画像と同じサイズ.適当にドーナツ型を描画してある 25 cv::Mat Mask = cv::Mat::zeros( ForeImg.size(), CV_8U ); 26 cv::circle( Mask, cv::Point( Mask.cols/2, Mask.rows/2 ), Mask.rows/3, cv::Scalar(255), -1 ); 27 cv::circle( Mask, cv::Point( Mask.cols/2, Mask.rows/2 ), Mask.rows/8, cv::Scalar(0), -1 ); 28 cv::imshow( "Mask", Mask ); 29 30 //前景画像のうち,マスクが白い範囲だけを背景画像上に描画する 31 ForeImg.copyTo( 32 BkImg( cv::Rect( 0,0, ForeImg.cols, ForeImg.rows ) ), //描画対象には前景画像と同じサイズの部分領域を指定する 33 Mask 34 ); 35 cv::imshow( "Result", BkImg ); 36 cv::waitKey(0); 37 return 0; 38}

背景画像:
イメージ説明

前景画像:
イメージ説明

マスク:
イメージ説明

copyTo の結果:
イメージ説明

bit演算でやるにしても数行書けば良い(やり方はいくつかあるだろうが,以下のコードではリンクで示したwikipediaの手順にしてある).
(マスクを3chなデータで作るのがダサい感)

C++

1//前景画像のうち,マスクが白い範囲だけを背景画像上に描画する 2{//※ただしここでは Mask は 8UC3 である 3 cv::Mat TgtReg = BkImg( cv::Rect( 0,0, ForeImg.cols, ForeImg.rows ) ); 4 cv::bitwise_and( TgtReg, ~Mask, TgtReg ); 5 6 cv::Mat Extracted; 7 ForeImg.copyTo( Extracted, Mask ); 8 cv::bitwise_or( TgtReg, Extracted, TgtReg ); 9}

投稿2024/01/26 04:39

編集2024/01/29 01:53
fana

総合スコア12247

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

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

fana

2024/01/26 04:57

念のため補足しておく: OpenCV の Mat の copyTo で所望のことをするにはコピー元とコピー先のサイズを合わせる必要がある. やることを想像するに,コピー先の画像バッファの方が大きかったりするのだろうから,その場合はコピー元と同じサイズの部分領域なMatをコピー先として指定する必要がある. (サイズ違いのときに何が起こるのか?についてはリファレンスを参照のこと.その結果は所望の動作ではないであろうと想像する)
zen434272

2024/01/26 10:42

copytoは角ではなく辺での指定ではなかったでしょうかよって長方形か正方形しかできないと認識しています。 bitwiseなどの使い方プログラムの作り方がわからないため質問しています。
fana

2024/01/27 02:50

copyTo にマスクを指定することで「長方形」のうちのマスクで指定した範囲だけをコピーできるわけですが,それは所望の処理ではないということですか? 正直こちらには「何がわからないのか」「どこが所望の話と違うのか」がわからないのですが.
fana

2024/01/27 03:08

bit演算でやりたいのであれば,その話は回答内で示したリンク先(Wikipedia)で説明されている通りにやれば良いのではないかと思うのですが,一体何が障害になっているのでしょう?
fana

2024/01/29 02:05 編集

とりあえずC++での結果だけは示しておく. 「python(numpy?)ならば別の方法で簡単にできる」みたいな話もあり得るのかもしれんが,そこは私は知らないので,OpenCV の関数を使う方法のみを示すにとどまる. とりあえずコードは読めなくとも,コメントと結果の絵くらいを見れば,私がどのような処理を想定して回答なりを書いていたのか?という点が把握できるのではないかと思う. で,「本件でやりたいことはそういう話ではない」ということなのであれば…… (現在の質問文を他の誰が読んでも,このような話を想定するのではないか,と思うので)もっとやりたいことを明確化するのが良かろうと思う. その際に 必要/便利/etc であれば,この「間違っている」回答をやり玉に挙げて多少ディスってもらっても別に構わない.(「既存の回答は何故かこんな話をしているけど,そういうことじゃなくて…」だとか)
zen434272

2024/01/29 21:10

ありがとうございます🙏🏻
zen434272

2024/01/29 21:15

https://www.web-dev-qa-db-ja.com/ja/python/opencv%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E7%94%BB%E5%83%8F%E3%81%8B%E3%82%89%E5%87%B9%E5%A4%9A%E8%A7%92%E5%BD%A2%E3%82%92%E3%83%88%E3%83%AA%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8Bpython/836552106/ このサイトの1番下のコード通りに打ち込んで、そこから背景をほかの画像にしたいのですが、どこを変えればいいのかわからないです。
zen434272

2024/01/29 21:16

出来れば変えたコードを教えて頂きたいです。
fana

2024/01/30 01:25

既述の通り,私はpythonを全く知らないので,方法論的な部分を示すことはできても python の具体コードを示すことはできません. なので,そこが必要であればやはり他者からの回答に期待するしかないです. (ちょっと前までは,こういう python + OpenCV な質問は即回答が付いてた気がするんだけどなぁ)
fana

2024/01/30 01:40 編集

あなたは既に 回答内でリンクを示した wikipedia のページの「画像マスク」節のところに示されている「スプライト(左)とマスク(右)のビットマップ画像」に相当する2つの画像を持っているのだと思う: * 前者(周りが黒い画像)は期せずして生成できている * 後者(マスク)は存在している(手持ちのマスクと白黒が逆だったら反転すればいい) …ので,そしたらあとは説明通りに マスクをAND(bitwise_andでやる) → スプライトをOR(bitwise_orでやる) みたいな処理をすれば良いだけだと思うのですが. pythonの事情を知らない人からすると「2行くらいのコード書けば終わるのでは?」と想像するのですが,実際は何かしら難しいんですかね?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問