回答編集履歴

2

サンプルコード追記

2016/07/12 14:27

投稿

catsforepaw
catsforepaw

スコア5938

test CHANGED
@@ -19,3 +19,265 @@
19
19
 
20
20
 
21
21
  ただし、OpenCVのウィンドウ表示機能では細かい制御ができないので、自前でウィンドウを作成/表示させないと無理かもしれません。
22
+
23
+
24
+
25
+ ---
26
+
27
+ 追記
28
+
29
+ カラーキーを指定して、その色の部分を透過させるウィンドウの実装例です。画像ファイルのパスや背景のサイズは適当に調整してください。
30
+
31
+ ```C++
32
+
33
+ #include "opencv2\opencv.hpp"
34
+
35
+ #include <windows.h>
36
+
37
+ #include <atlbase.h>
38
+
39
+ #include <atlwin.h>
40
+
41
+
42
+
43
+ // cv::waitKeyの自前実装版
44
+
45
+ static int sKey = 0;
46
+
47
+ int myWaitKey(int iWaitTime)
48
+
49
+ {
50
+
51
+ ULONGLONG timeup = ::GetTickCount64() + iWaitTime;
52
+
53
+ do
54
+
55
+ {
56
+
57
+ MSG msg;
58
+
59
+ while(::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
60
+
61
+ {
62
+
63
+ if(msg.message == WM_QUIT)
64
+
65
+ return -1;
66
+
67
+ ::TranslateMessage(&msg);
68
+
69
+ ::DispatchMessage(&msg);
70
+
71
+ }
72
+
73
+ } while(sKey == 0 && (iWaitTime == 0 || ::GetTickCount64() < timeup));
74
+
75
+ int key = sKey;
76
+
77
+ sKey = 0;
78
+
79
+ return key;
80
+
81
+ }
82
+
83
+
84
+
85
+ // カラーキーを使った透過ウィンドウの実装例
86
+
87
+ class ColorKeyWindow : public ATL::CWindowImpl<ColorKeyWindow>
88
+
89
+ {
90
+
91
+ cv::Mat mImage;
92
+
93
+
94
+
95
+ public:
96
+
97
+ DECLARE_WND_CLASS(L"ColorKeyWindow-Class");
98
+
99
+
100
+
101
+ // コンストラクタでウィンドウを作成し、カラーキーを設定
102
+
103
+ ColorKeyWindow(const wchar_t * iName, COLORREF iColorKey = RGB(0,0,255))
104
+
105
+ {
106
+
107
+ RECT rc = {0, 0, 0, 0};
108
+
109
+ HWND hwnd = this->Create(nullptr, rc, iName, WS_POPUP, WS_EX_LAYERED);
110
+
111
+ ::SetLayeredWindowAttributes(hwnd, iColorKey, 0, LWA_COLORKEY);
112
+
113
+ }
114
+
115
+
116
+
117
+ // デストラクタでウィンドウ破棄
118
+
119
+ ~ColorKeyWindow()
120
+
121
+ {
122
+
123
+ this->DestroyWindow();
124
+
125
+ }
126
+
127
+
128
+
129
+ // 画像表示
130
+
131
+ void ShowImage(const cv::Mat & iMat)
132
+
133
+ {
134
+
135
+ mImage = iMat.clone();
136
+
137
+ this->SetWindowPos(nullptr, 0, 0, mImage.cols, mImage.rows, SWP_NOMOVE|SWP_NOZORDER|SWP_SHOWWINDOW);
138
+
139
+ // 実際にはWM_PAINTで表示
140
+
141
+ this->Invalidate(FALSE);
142
+
143
+ }
144
+
145
+
146
+
147
+ private:
148
+
149
+ BEGIN_MSG_MAP(HelloWindow)
150
+
151
+ MESSAGE_HANDLER(WM_PAINT, OnPaint)
152
+
153
+ MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
154
+
155
+ MESSAGE_HANDLER(WM_CHAR, OnChar)
156
+
157
+ END_MSG_MAP()
158
+
159
+
160
+
161
+ LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
162
+
163
+ {
164
+
165
+ PAINTSTRUCT ps;
166
+
167
+ HDC hdc = BeginPaint(&ps);
168
+
169
+ if(!mImage.empty())
170
+
171
+ {
172
+
173
+ BITMAPINFO bmi = {0};
174
+
175
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
176
+
177
+ bmi.bmiHeader.biWidth = mImage.cols;
178
+
179
+ bmi.bmiHeader.biHeight = -mImage.rows;
180
+
181
+ bmi.bmiHeader.biPlanes = 1;
182
+
183
+ bmi.bmiHeader.biBitCount = mImage.channels() * 8;
184
+
185
+ bmi.bmiHeader.biClrImportant = BI_RGB;
186
+
187
+ ::SetDIBitsToDevice(hdc, 0, 0, mImage.cols, mImage.rows, 0, 0, 0, mImage.rows, mImage.ptr(0), &bmi, DIB_RGB_COLORS);
188
+
189
+ }
190
+
191
+ EndPaint(&ps);
192
+
193
+ return 0;
194
+
195
+ }
196
+
197
+
198
+
199
+ LRESULT OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
200
+
201
+ {
202
+
203
+ // ウィンドウをマウスで移動できるようにする
204
+
205
+ return HTCAPTION;
206
+
207
+ }
208
+
209
+
210
+
211
+ LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
212
+
213
+ {
214
+
215
+ sKey = (int)wParam;
216
+
217
+ return 0;
218
+
219
+ }
220
+
221
+ };
222
+
223
+
224
+
225
+ // サンプルプログラム
226
+
227
+ int main(int argc, char* argv[])
228
+
229
+ {
230
+
231
+ cv::Mat image = cv::imread("lena.jpg");
232
+
233
+ cv::Mat bgimage(cv::Size(800, 800), CV_8UC3);
234
+
235
+
236
+
237
+ ColorKeyWindow window(L"MyWindow");
238
+
239
+
240
+
241
+ int angle = 0;
242
+
243
+ while(1)
244
+
245
+ {
246
+
247
+ bgimage = cv::Scalar(255, 0, 0); // ブルーバックでクリア
248
+
249
+
250
+
251
+ cv::Point2d center(image.cols / 2, image.rows / 2);
252
+
253
+ cv::Mat mat = cv::getRotationMatrix2D(center, angle, 1.0);
254
+
255
+ mat.at<double>(0, 2) += (bgimage.cols - image.cols) / 2;
256
+
257
+ mat.at<double>(1, 2) += (bgimage.rows - image.rows) / 2;
258
+
259
+ cv::warpAffine(image, bgimage, mat, bgimage.size(), cv::INTER_LINEAR, cv::BORDER_TRANSPARENT);
260
+
261
+ angle = (angle + 360 - 1) % 360;
262
+
263
+
264
+
265
+ window.ShowImage(bgimage);
266
+
267
+
268
+
269
+ int key = myWaitKey(1);
270
+
271
+ if(key == '\x1b')
272
+
273
+ break;
274
+
275
+ }
276
+
277
+ return 0;
278
+
279
+ }
280
+
281
+ ```
282
+
283
+

1

書き忘れ

2016/07/12 14:27

投稿

catsforepaw
catsforepaw

スコア5938

test CHANGED
@@ -14,7 +14,7 @@
14
14
 
15
15
 
16
16
 
17
- 1は`SetWindowRgn`関数、2と3はレイヤードウィンドウに設定した上で`SetLayeredWindowAttributes`関数で、比較的簡単に実現可能です。
17
+ 1は`SetWindowRgn`関数、2と3はレイヤードウィンドウに設定した上で`SetLayeredWindowAttributes`関数と`UpdateLayeredWindow`関数で、比較的簡単に実現可能です。
18
18
 
19
19
 
20
20