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

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

corner.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_CORNER__
35 #define __INCLUDE_MIST_CORNER__
36
37
38 #ifndef __INCLUDE_MIST_H__
39 #include "../mist.h"
40 #endif
41
42 #ifndef __INCLUDE_MIST_VECTOR__
43 #include "../vector.h"
44 #endif
45
46 #ifndef __INCLUDE_MIST_LIMITS__
47 #include "../limits.h"
48 #endif
49
50 #ifndef __INCLUDE_MIST_VECTOR__
51 #include "../vector.h"
52 #endif
53
54 #ifndef __INCLUDE_CONVERTER__
55 #include "../converter.h"
56 #endif
57
58 #ifndef __INCLUDE_MIST_THREAD__
59 #include "../thread.h"
60 #endif
61
62 #ifndef __INCLUDE_FILTER_LINEAR_FILTER_H__
63 #include "linear.h"
64 #endif
65
66 #include <vector>
67 #include <algorithm>
68
69
70 // mist名前空間の始まり
71 _MIST_BEGIN
72
73
74
75 namespace __corner_utility__
76 {
77 struct corner_position
78 {
79 int x;
80 int y;
81 double key;
82
84 corner_position( ){ }
85
87 corner_position( int xx, int yy, double k ) : x( xx ), y( yy ), key( k ){ }
88
90 bool operator <( const corner_position &f ) const
91 {
92 return( key < f.key );
93 }
94
96 static bool greater( const corner_position &f1, const corner_position &f2 )
97 {
98 return( f2 < f1 );
99 }
100 };
101 }
102
103
111
112
126 template < class T, class Allocator, template < typename, typename > class LIST, class TT, class AAllocator >
127 typename array2< T, Allocator >::difference_type harris( const array2< T, Allocator > &in, LIST< vector2< TT >, AAllocator >&out, typename array2< T, Allocator >::size_type max_corners,
128 double min_distance, double kappa = 0.04, typename array2< T, Allocator >::size_type window_size = 3 )
129 {
130 typedef typename array2< T, Allocator >::size_type size_type;
131 typedef typename array2< T, Allocator >::difference_type difference_type;
132
133 if( in.empty( ) )
134 {
135 return( -1 );
136 }
137
138 typedef array2< double > image_type;
139 typedef vector2< TT > ovector_type;
140 typedef rgb< double > vector_type;
141 typedef array2< vector_type > vector_image_type;
142 typedef array2< unsigned char > mask_type;
143
144 image_type tmp, k1( 3, 3 ), k2( 3, 3 ), gx, gy;
145
146 convert( in, tmp );
147
148 k1( 0, 0 ) = -1; k1( 1, 0 ) = 0; k1( 2, 0 ) = 1;
149 k1( 0, 1 ) = -2; k1( 1, 1 ) = 0; k1( 2, 1 ) = 2;
150 k1( 0, 2 ) = -1; k1( 1, 2 ) = 0; k1( 2, 2 ) = 1;
151
152 k2( 0, 0 ) = -1; k2( 1, 0 ) = -2; k2( 2, 0 ) = -1;
153 k2( 0, 1 ) = 0; k2( 1, 1 ) = 0; k2( 2, 1 ) = 0;
154 k2( 0, 2 ) = +1; k2( 1, 2 ) = +2; k2( 2, 2 ) = +1;
155
156 linear_filter( tmp, gx, k1 );
157 linear_filter( tmp, gy, k2 );
158
159 vector_image_type work( in.width( ), in.height( ) ), wwork;
160
161 #ifdef _OPENMP
162 #pragma omp parallel for schedule( guided )
163 #endif
164 for( int j = 0 ; j < static_cast< int >( tmp.height( ) ) ; j++ )
165 {
166 for( size_type i = 0 ; i < tmp.width( ) ; i++ )
167 {
168 double dx = gx( i, j );
169 double dy = gy( i, j );
170
171 work( i, j ) = vector_type( dx * dx, dy * dy, dx * dy );
172 }
173 }
174
175 #if 0
176 window_size /= 2;
177 gaussian_filter( work, wwork, window_size * 0.5 );
178 #else
179 average_filter( work, wwork, window_size, window_size );
180 #endif
181
182 mask_type mask( in.width( ), in.height( ) );
183
184 typedef __corner_utility__::corner_position point_type;
185 typedef std::vector< point_type > point_list_type;
186 point_list_type point_list, out_list;
187
188 for( size_type j = 1 ; j < wwork.height( ) - 1 ; j++ )
189 {
190 for( size_type i = 1 ; i < wwork.width( ) - 1 ; i++ )
191 {
192 const vector_type &v = wwork( i, j );
193 double Mc = v.r * v.g - v.b * v.b - kappa * ( v.r + v.g ) * ( v.r + v.g );
194
195 if( Mc > 0 )
196 {
197 point_list.push_back( point_type( i, j, Mc ) );
198 }
199 }
200 }
201
202 std::sort( point_list.begin( ), point_list.end( ), __corner_utility__::corner_position::greater );
203
204 min_distance = min_distance * min_distance;
205 for( size_type i = 0 ; i < point_list.size( ) && out_list.size( ) < max_corners ; i++ )
206 {
207 const point_type &v = point_list[ i ];
208
209 bool flag = true;
210 for( size_type l = 0 ; l < out_list.size( ) ; l++ )
211 {
212 const point_type &u = out_list[ l ];
213 if( ( v.x - u.x ) * ( v.x - u.x ) + ( v.y - u.y ) * ( v.y - u.y ) < min_distance )
214 {
215 flag = false;
216 break;
217 }
218 }
219
220 if( flag )
221 {
222 out_list.push_back( v );
223 }
224 }
225
226 out.clear( );
227
228 for( size_type i = 0 ; i < out_list.size( ) ; i++ )
229 {
230 out.push_back( ovector_type( out_list[ i ].x, out_list[ i ].y ) );
231 }
232
233 return( out.size( ) );
234 }
235
236
237
239 // コーナー検出フィルタグループの終わり
240
241
242 // mist名前空間の終わり
243 _MIST_END
244
245
246 #endif // __INCLUDE_MIST_CORNER__
247