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

回答編集履歴

2

bit演算の処理も追記しておく

2024/01/29 01:53

投稿

fana
fana

スコア12247

answer CHANGED
@@ -63,4 +63,18 @@
63
63
  ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/52463cb7-cd1a-4bc1-a1ad-30890096ada9.png)
64
64
 
65
65
  `copyTo` の結果:
66
- ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/386a0851-8ac1-4476-81ee-9e47fd00f550.png)
66
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/386a0851-8ac1-4476-81ee-9e47fd00f550.png)
67
+
68
+ bit演算でやるにしても数行書けば良い(やり方はいくつかあるだろうが,以下のコードではリンクで示したwikipediaの手順にしてある).
69
+ (マスクを3chなデータで作るのがダサい感)
70
+ ```C++
71
+ //前景画像のうち,マスクが白い範囲だけを背景画像上に描画する
72
+ {//※ただしここでは Mask は 8UC3 である
73
+ cv::Mat TgtReg = BkImg( cv::Rect( 0,0, ForeImg.cols, ForeImg.rows ) );
74
+ cv::bitwise_and( TgtReg, ~Mask, TgtReg );
75
+
76
+ cv::Mat Extracted;
77
+ ForeImg.copyTo( Extracted, Mask );
78
+ cv::bitwise_or( TgtReg, Extracted, TgtReg );
79
+ }
80
+ ```

1

copyTo の結果を示す

2024/01/29 01:36

投稿

fana
fana

スコア12247

answer CHANGED
@@ -2,4 +2,65 @@
2
2
  (私は Python から OpenCV 使ったことないので,そこらへんの事情とかわかりませんが)
3
3
 
4
4
  仮に上記が使えないのだとしても,あなたが示した参考先を見た感じだと `bitwise_and` とかは普通に使えるのでしょうから,そういうのを用いて都合が良い処理を組み立てるのではダメなのですか?
5
- [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B9%E3%82%AF_(%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6)) でも説明あるみたいですが.
5
+ [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%82%B9%E3%82%AF_(%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6)) でも説明あるみたいですが.
6
+
7
+ ---
8
+
9
+ [追記]
10
+ とりあえず `copyTo` のサンプルを示しておく.C++だが.
11
+
12
+ ※やりたいことは単にこういう話ではないのか? と読んだのだが,違うのだろうか?
13
+ 違うならば,他者からの的確な回答を得るためにはその旨が明確になるよう質問文の内容を考えた方が良いのでは.
14
+
15
+ ```C++
16
+ int main()
17
+ {
18
+ //背景画像
19
+ cv::Mat BkImg( 200, 160, CV_8UC3 );
20
+ for( int x=0; x<BkImg.cols; ++x )
21
+ {//※真っ白とかだと話が分かり難い様子なので,適当な模様を描画しておく
22
+ unsigned char R = (unsigned char)( 128 + 120 * cos( x*0.05 ) );
23
+ unsigned char B = 255 - R;
24
+ cv::line( BkImg, cv::Point(x,0), cv::Point(x,BkImg.rows), cv::Scalar(B,0,R) );
25
+ }
26
+ cv::imshow( "BkImg", BkImg );
27
+
28
+ //前景画像
29
+ cv::Mat ForeImg( 120, 100, CV_8UC3 );
30
+ for( int y=0; y<ForeImg.rows; ++y )
31
+ {//※適当に背景とは異なる模様を描画している
32
+ unsigned char G = (unsigned char)( 128 + 120 * cos( y*0.1 ) );
33
+ unsigned char R = 255 - G;
34
+ unsigned char B = R / 2;
35
+ cv::line( ForeImg, cv::Point(0,y), cv::Point(ForeImg.cols,y), cv::Scalar(B,G,R) );
36
+ }
37
+ cv::imshow( "ForeImg", ForeImg );
38
+
39
+ //マスク.前景画像と同じサイズ.適当にドーナツ型を描画してある
40
+ cv::Mat Mask = cv::Mat::zeros( ForeImg.size(), CV_8U );
41
+ cv::circle( Mask, cv::Point( Mask.cols/2, Mask.rows/2 ), Mask.rows/3, cv::Scalar(255), -1 );
42
+ cv::circle( Mask, cv::Point( Mask.cols/2, Mask.rows/2 ), Mask.rows/8, cv::Scalar(0), -1 );
43
+ cv::imshow( "Mask", Mask );
44
+
45
+ //前景画像のうち,マスクが白い範囲だけを背景画像上に描画する
46
+ ForeImg.copyTo(
47
+ BkImg( cv::Rect( 0,0, ForeImg.cols, ForeImg.rows ) ), //描画対象には前景画像と同じサイズの部分領域を指定する
48
+ Mask
49
+ );
50
+ cv::imshow( "Result", BkImg );
51
+ cv::waitKey(0);
52
+ return 0;
53
+ }
54
+ ```
55
+
56
+ 背景画像:
57
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/e1395da6-503c-4176-98d4-a6c9944baf85.png)
58
+
59
+ 前景画像:
60
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/d865cbcb-d366-47e7-82a6-1d8a395c77c2.png)
61
+
62
+ マスク:
63
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/52463cb7-cd1a-4bc1-a1ad-30890096ada9.png)
64
+
65
+ `copyTo` の結果:
66
+ ![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2024-01-29/386a0851-8ac1-4476-81ee-9e47fd00f550.png)