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名前空間の始まり
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 

Generated on Wed Nov 12 2014 19:44:15 for MIST by doxygen 1.8.1.2