- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

interlace.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28
33
34 #ifndef __INCLUDE_MIST_INTERLACE__
35 #define __INCLUDE_MIST_INTERLACE__
36
37
38 #ifndef __INCLUDE_MIST_H__
39 #include "../mist.h"
40 #endif
41
42 // カラー画像の設定を読み込む
43 #ifndef __INCLUDE_MIST_COLOR_H__
44 #include "../config/color.h"
45 #endif
46
47
48
49 // mist名前空間の始まり
50 _MIST_BEGIN
51
52
53 namespace __interlace_controller__
54 {
55 template < bool b >
56 struct interlace_controller
57 {
58 template < class T, class Allocator >
59 static bool interlace_odd_row( const array2< T, Allocator > &in, array2< T, Allocator > &out )
60 {
61 typedef typename array2< T, Allocator >::size_type size_type;
62 typedef typename array2< T, Allocator >::value_type value_type;
63
64 if( in.height( ) < 2 )
65 {
66 // 2行以上ない場合はインターレス除去はできない
67 return( false );
68 }
69
70 out = in;
71
72 size_type i, j;
73
74 // 奇数ラインを補間するため，先頭行を次の行で補完する
75 for( i = 0 ; i < in.width( ) ; i++ )
76 {
77 out( i, 0 ) = in( i, 1 );
78 }
79 // 各奇数行を前後の偶数行で線形に補完してうめる
80 for( j = 2 ; j < in.height( ) - 1 ; j += 2 )
81 {
82 for( i = 0 ; i < in.width( ) ; i++ )
83 {
84 out( i, j ) = static_cast< value_type >( ( in( i, j - 1 ) + in( i, j + 1 ) ) / 2.0 );
85 }
86 }
87 // 最終行が奇数のため，1行前で補完する
88 if( j == in.height( ) - 1 )
89 {
90 for( i = 0 ; i < in.width( ) ; i++ )
91 {
92 out( i, j ) = in( i, j - 1 );
93 }
94 }
95 return( true );
96 }
97
98 template < class T, class Allocator >
99 static bool interlace_odd_col( const array2< T, Allocator > &in, array2< T, Allocator > &out )
100 {
101 typedef typename array2< T, Allocator >::size_type size_type;
102 typedef typename array2< T, Allocator >::value_type value_type;
103
104 if( in.width( ) < 2 )
105 {
106 // 2列以上ない場合はインターレス除去はできない
107 return( false );
108 }
109
110 out = in;
111
112 size_type i, j;
113
114 // 奇数ラインを補間するため，先頭列を次の列で補完する
115 for( i = 0 ; i < in.height( ) ; i++ )
116 {
117 out( 0, i ) = in( 1, i );
118 }
119 // 各奇数行を前後の偶数行で線形に補完してうめる
120 for( j = 0 ; j < in.height( ) ; j++ )
121 {
122 for( i = 2 ; i < in.width( ) - 1 ; i += 2 )
123 {
124 out( i, j ) = static_cast< value_type >( ( in( i - 1, j ) + in( i + 1, j ) ) / 2.0 );
125 }
126
127 // 最終列が奇数のため，1列前で補完する
128 if( i == in.width( ) - 1 )
129 {
130 out( i, j ) = in( i - 1, j );
131 }
132 }
133 return( true );
134 }
135
136 template < class T, class Allocator >
137 static bool interlace_even_row( const array2< T, Allocator > &in, array2< T, Allocator > &out )
138 {
139 typedef typename array2< T, Allocator >::size_type size_type;
140 typedef typename array2< T, Allocator >::value_type value_type;
141
142 if( in.height( ) < 2 )
143 {
144 // 2行以上ない場合はインターレス除去はできない
145 return( false );
146 }
147
148 out = in;
149
150 size_type i, j;
151
152 // 各偶数行を前後の奇数行で線形に補完してうめる
153 for( j = 1 ; j < in.height( ) - 1 ; j += 2 )
154 {
155 for( i = 0 ; i < in.width( ) ; i++ )
156 {
157 out( i, j ) = static_cast< value_type >( ( in( i, j - 1 ) + in( i, j + 1 ) ) / 2.0 );
158 }
159 }
160 // 最終行が偶数のため，1行前で補完する
161 if( j == in.height( ) - 1 )
162 {
163 for( i = 0 ; i < in.width( ) ; i++ )
164 {
165 out( i, j ) = in( i, j - 1 );
166 }
167 }
168 return( true );
169 }
170
171 template < class T, class Allocator >
172 static bool interlace_even_col( const array2< T, Allocator > &in, array2< T, Allocator > &out )
173 {
174 typedef typename array2< T, Allocator >::size_type size_type;
175 typedef typename array2< T, Allocator >::value_type value_type;
176
177 if( in.width( ) < 2 )
178 {
179 // 2列以上ない場合はインターレス除去はできない
180 return( false );
181 }
182
183 out = in;
184
185 size_type i, j;
186
187 // 各奇数行を前後の偶数行で線形に補完してうめる
188 for( j = 0 ; j < in.height( ) ; j++ )
189 {
190 for( i = 1 ; i < in.width( ) - 1 ; i += 2 )
191 {
192 out( i, j ) = static_cast< value_type >( ( in( i - 1, j ) + in( i + 1, j ) ) / 2.0 );
193 }
194
195 // 最終列が偶数のため，1列前で補完する
196 if( i == in.width( ) - 1 )
197 {
198 out( i, j ) = in( i - 1, j );
199 }
200 }
201 return( true );
202 }
203 };
204
205 template < >
206 struct interlace_controller< true >
207 {
208 template < class T, class Allocator >
209 static bool interlace_odd_row( const array2< T, Allocator > &in, array2< T, Allocator > &out )
210 {
211 typedef typename array2< T, Allocator >::size_type size_type;
212 typedef typename array2< T, Allocator >::value_type color_type;
213 typedef typename color_type::value_type value_type;
214
215 if( in.height( ) < 2 )
216 {
217 // 2行以上無い場合はインターレス除去はできない
218 return( false );
219 }
220
221 out = in;
222
223 size_type i, j;
224 double r, g, b;
225
226 // 奇数ラインを補間するため，先頭行を次の行で補完する
227 for( i = 0 ; i < in.width( ) ; i++ )
228 {
229 out( i, 0 ) = in( i, 1 );
230 }
231 // 各奇数行を前後の偶数行で線形に補完してうめる
232 for( j = 2 ; j < in.height( ) - 1 ; j += 2 )
233 {
234 for( i = 0 ; i < in.width( ) ; i++ )
235 {
236 r = ( in( i, j - 1 ).r + in( i, j + 1 ).r ) / 2.0;
237 g = ( in( i, j - 1 ).g + in( i, j + 1 ).g ) / 2.0;
238 b = ( in( i, j - 1 ).b + in( i, j + 1 ).b ) / 2.0;
239 out( i, j ) = color_type( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
240 }
241 }
242 // 最終行が奇数のため，1行前で補完する
243 if( j == in.height( ) - 1 )
244 {
245 for( i = 0 ; i < in.width( ) ; i++ )
246 {
247 out( i, j ) = in( i, j - 1 );
248 }
249 }
250 return( true );
251 }
252
253 template < class T, class Allocator >
254 static bool interlace_odd_col( const array2< T, Allocator > &in, array2< T, Allocator > &out )
255 {
256 typedef typename array2< T, Allocator >::size_type size_type;
257 typedef typename array2< T, Allocator >::value_type color_type;
258 typedef typename color_type::value_type value_type;
259
260 if( in.width( ) < 2 )
261 {
262 // 2列以上ない場合はインターレス除去はできない
263 return( false );
264 }
265
266 out = in;
267
268 size_type i, j;
269 double r, g, b;
270
271 // 奇数ラインを補間するため，先頭列を次の列で補完する
272 for( i = 0 ; i < in.height( ) ; i++ )
273 {
274 out( 0, i ) = in( 1, i );
275 }
276 // 各奇数行を前後の偶数行で線形に補完してうめる
277 for( j = 0 ; j < in.height( ) ; j++ )
278 {
279 for( i = 2 ; i < in.width( ) - 1 ; i += 2 )
280 {
281 r = ( in( i - 1, j ).r + in( i + 1, j ).r ) / 2.0;
282 g = ( in( i - 1, j ).g + in( i + 1, j ).g ) / 2.0;
283 b = ( in( i - 1, j ).b + in( i + 1, j ).b ) / 2.0;
284 out( i, j ) = color_type( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
285 }
286
287 // 最終列が奇数のため，1列前で補完する
288 if( i == in.width( ) - 1 )
289 {
290 out( i, j ) = in( i - 1, j );
291 }
292 }
293 return( true );
294 }
295
296 template < class T, class Allocator >
297 static bool interlace_even_row( const array2< T, Allocator > &in, array2< T, Allocator > &out )
298 {
299 typedef typename array2< T, Allocator >::size_type size_type;
300 typedef typename array2< T, Allocator >::value_type color_type;
301 typedef typename color_type::value_type value_type;
302
303 if( in.height( ) < 2 )
304 {
305 // 2行以上無い場合はインターレス除去はできない
306 return( false );
307 }
308
309 out = in;
310
311 size_type i, j;
312 double r, g, b;
313
314 for( j = 1 ; j < in.height( ) - 1 ; j += 2 )
315 {
316 for( i = 0 ; i < in.width( ) ; i++ )
317 {
318 r = ( in( i, j - 1 ).r + in( i, j + 1 ).r ) / 2.0;
319 g = ( in( i, j - 1 ).g + in( i, j + 1 ).g ) / 2.0;
320 b = ( in( i, j - 1 ).b + in( i, j + 1 ).b ) / 2.0;
321 out( i, j ) = color_type( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
322 }
323 }
324 if( j == in.height( ) - 1 )
325 {
326 for( i = 0 ; i < in.width( ) ; i++ )
327 {
328 out( i, j ) = in( i, j - 1 );
329 }
330 }
331 return( true );
332 }
333
334 template < class T, class Allocator >
335 static bool interlace_even_col( const array2< T, Allocator > &in, array2< T, Allocator > &out )
336 {
337 typedef typename array2< T, Allocator >::size_type size_type;
338 typedef typename array2< T, Allocator >::value_type color_type;
339 typedef typename color_type::value_type value_type;
340
341 if( in.width( ) < 2 )
342 {
343 // 2列以上ない場合はインターレス除去はできない
344 return( false );
345 }
346
347 out = in;
348
349 size_type i, j;
350 double r, g, b;
351
352 // 各奇数行を前後の偶数行で線形に補完してうめる
353 for( j = 0 ; j < in.height( ) ; j++ )
354 {
355 for( i = 1 ; i < in.width( ) - 1 ; i += 2 )
356 {
357 r = ( in( i - 1, j ).r + in( i + 1, j ).r ) / 2.0;
358 g = ( in( i - 1, j ).g + in( i + 1, j ).g ) / 2.0;
359 b = ( in( i - 1, j ).b + in( i + 1, j ).b ) / 2.0;
360 out( i, j ) = color_type( static_cast< value_type >( r ), static_cast< value_type >( g ), static_cast< value_type >( b ) );
361 }
362
363 // 最終列が偶数のため，1列前で補完する
364 if( i == in.width( ) - 1 )
365 {
366 out( i, j ) = in( i - 1, j );
367 }
368 }
369 return( true );
370 }
371 };
372 }
373
374
382
383
396 template < class T, class Allocator >
397 bool interlace( const array2< T, Allocator > &in, array2< T, Allocator > &out, bool is_odd_line = false, bool is_row_interlace = true )
398 {
399 if( is_odd_line )
400 {
401 if( is_row_interlace )
402 {
403 return( __interlace_controller__::interlace_controller< is_color< T >::value >::interlace_odd_row( in, out ) );
404 }
405 else
406 {
407 return( __interlace_controller__::interlace_controller< is_color< T >::value >::interlace_odd_col( in, out ) );
408 }
409 }
410 else
411 {
412 if( is_row_interlace )
413 {
414 return( __interlace_controller__::interlace_controller< is_color< T >::value >::interlace_even_row( in, out ) );
415 }
416 else
417 {
418 return( __interlace_controller__::interlace_controller< is_color< T >::value >::interlace_even_col( in, out ) );
419 }
420 }
421 }
422
423
425 // インターレス除去グループの終わり
426
427
428 // mist名前空間の終わり
429 _MIST_END
430
431
432 #endif // __INCLUDE_MIST_INTERLACE__
433