1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
51 calcMinEigenVal( const Mat& _cov, Mat& _dst )
54 Size size = _cov.size();
55 if( _cov.isContinuous() && _dst.isContinuous() )
57 size.width *= size.height;
61 __m128 half = _mm_set1_ps(0.5f);
64 for( i = 0; i < size.height; i++ )
66 const float* cov = (const float*)(_cov.data + _cov.step*i);
67 float* dst = (float*)(_dst.data + _dst.step*i);
70 for( ; j <= size.width - 5; j += 4 )
72 __m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
73 __m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
74 __m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
75 __m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
77 t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
78 c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
79 b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
80 c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
81 a = _mm_movelh_ps(t, b);
82 b = _mm_movehl_ps(b, t);
83 a = _mm_mul_ps(a, half);
84 c = _mm_mul_ps(c, half);
86 t = _mm_add_ps(_mm_mul_ps(t, t), _mm_mul_ps(b,b));
87 a = _mm_sub_ps(_mm_add_ps(a, c), _mm_sqrt_ps(t));
88 _mm_storeu_ps(dst + j, a);
91 for( ; j < size.width; j++ )
93 double a = cov[j*3]*0.5;
94 double b = cov[j*3+1];
95 double c = cov[j*3+2]*0.5;
96 dst[j] = (float)((a + c) - std::sqrt((a - c)*(a - c) + b*b));
103 calcHarris( const Mat& _cov, Mat& _dst, double k )
106 Size size = _cov.size();
107 if( _cov.isContinuous() && _dst.isContinuous() )
109 size.width *= size.height;
113 __m128 k4 = _mm_set1_ps((float)k);
116 for( i = 0; i < size.height; i++ )
118 const float* cov = (const float*)(_cov.data + _cov.step*i);
119 float* dst = (float*)(_dst.data + _dst.step*i);
123 for( ; j <= size.width - 5; j += 4 )
125 __m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
126 __m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
127 __m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
128 __m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
130 t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
131 c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
132 b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
133 c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
134 a = _mm_movelh_ps(t, b);
135 b = _mm_movehl_ps(b, t);
136 t = _mm_add_ps(a, c);
137 a = _mm_sub_ps(_mm_mul_ps(a, c), _mm_mul_ps(b, b));
138 t = _mm_mul_ps(_mm_mul_ps(t, t), k4);
139 a = _mm_sub_ps(a, t);
140 _mm_storeu_ps(dst + j, a);
144 for( ; j < size.width; j++ )
147 double b = cov[j*3+1];
148 double c = cov[j*3+2];
149 dst[j] = (float)(a*c - b*b - k*(a + c)*(a + c));
156 calcEigenValsVecs( const Mat& _cov, Mat& _dst )
159 Size size = _cov.size();
160 if( _cov.isContinuous() && _dst.isContinuous() )
162 size.width *= size.height;
166 for( i = 0; i < size.height; i++ )
168 const float* cov = (const float*)(_cov.data + _cov.step*i);
169 float* dst = (float*)(_dst.data + _dst.step*i);
171 for( j = 0; j < size.width; j++ )
174 double b = cov[j*3+1];
175 double c = cov[j*3+2];
177 double u = (a + c)*0.5;
178 double v = std::sqrt((a - c)*(a - c)*0.25 + b*b);
186 if( e + fabs(y) < 1e-4 )
191 if( e + fabs(y) < 1e-4 )
193 e = 1./(e + fabs(y) + FLT_EPSILON);
198 double d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
199 dst[6*j] = (float)l1;
200 dst[6*j + 2] = (float)(x*d);
201 dst[6*j + 3] = (float)(y*d);
207 if( e + fabs(y) < 1e-4 )
212 if( e + fabs(y) < 1e-4 )
214 e = 1./(e + fabs(y) + FLT_EPSILON);
219 d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
220 dst[6*j + 1] = (float)l2;
221 dst[6*j + 4] = (float)(x*d);
222 dst[6*j + 5] = (float)(y*d);
228 enum { MINEIGENVAL=0, HARRIS=1, EIGENVALSVECS=2 };
232 cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
233 int aperture_size, int op_type, double k=0.,
234 int borderType=BORDER_DEFAULT )
236 int depth = src.depth();
237 double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size;
238 if( aperture_size < 0 )
244 CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 );
247 if( aperture_size > 0 )
249 Sobel( src, Dx, CV_32F, 1, 0, aperture_size, scale, 0, borderType );
250 Sobel( src, Dy, CV_32F, 0, 1, aperture_size, scale, 0, borderType );
254 Scharr( src, Dx, CV_32F, 1, 0, scale, 0, borderType );
255 Scharr( src, Dy, CV_32F, 0, 1, scale, 0, borderType );
258 Size size = src.size();
259 Mat cov( size, CV_32FC3 );
262 for( i = 0; i < size.height; i++ )
264 float* cov_data = (float*)(cov.data + i*cov.step);
265 const float* dxdata = (const float*)(Dx.data + i*Dx.step);
266 const float* dydata = (const float*)(Dy.data + i*Dy.step);
268 for( j = 0; j < size.width; j++ )
270 float dx = dxdata[j];
271 float dy = dydata[j];
273 cov_data[j*3] = dx*dx;
274 cov_data[j*3+1] = dx*dy;
275 cov_data[j*3+2] = dy*dy;
279 boxFilter(cov, cov, cov.depth(), Size(block_size, block_size),
280 Point(-1,-1), false, borderType );
282 if( op_type == MINEIGENVAL )
283 calcMinEigenVal( cov, eigenv );
284 else if( op_type == HARRIS )
285 calcHarris( cov, eigenv, k );
286 else if( op_type == EIGENVALSVECS )
287 calcEigenValsVecs( cov, eigenv );
291 void cornerMinEigenVal( const Mat& src, Mat& dst, int blockSize, int ksize, int borderType )
293 dst.create( src.size(), CV_32F );
294 cornerEigenValsVecs( src, dst, blockSize, ksize, MINEIGENVAL, 0, borderType );
298 void cornerHarris( const Mat& src, Mat& dst, int blockSize, int ksize, double k, int borderType )
300 dst.create( src.size(), CV_32F );
301 cornerEigenValsVecs( src, dst, blockSize, ksize, HARRIS, k, borderType );
305 void cornerEigenValsAndVecs( const Mat& src, Mat& dst, int blockSize, int ksize, int borderType )
307 if( dst.rows != src.rows || dst.cols*dst.channels() != src.cols*6 || dst.depth() != CV_32F )
308 dst.create( src.size(), CV_32FC(6) );
309 cornerEigenValsVecs( src, dst, blockSize, ksize, EIGENVALSVECS, 0, borderType );
313 void preCornerDetect( const Mat& src, Mat& dst, int ksize, int borderType )
315 Mat Dx, Dy, D2x, D2y, Dxy;
317 CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 );
318 dst.create( src.size(), CV_32F );
320 Sobel( src, Dx, CV_32F, 1, 0, ksize, 1, 0, borderType );
321 Sobel( src, Dy, CV_32F, 0, 1, ksize, 1, 0, borderType );
322 Sobel( src, D2x, CV_32F, 2, 0, ksize, 1, 0, borderType );
323 Sobel( src, D2y, CV_32F, 0, 2, ksize, 1, 0, borderType );
324 Sobel( src, Dxy, CV_32F, 1, 1, ksize, 1, 0, borderType );
326 double factor = 1 << (ksize - 1);
327 if( src.depth() == CV_8U )
329 factor = 1./(factor * factor * factor);
331 Size size = src.size();
333 for( i = 0; i < size.height; i++ )
335 float* dstdata = (float*)(dst.data + i*dst.step);
336 const float* dxdata = (const float*)(Dx.data + i*Dx.step);
337 const float* dydata = (const float*)(Dy.data + i*Dy.step);
338 const float* d2xdata = (const float*)(D2x.data + i*D2x.step);
339 const float* d2ydata = (const float*)(D2y.data + i*D2y.step);
340 const float* dxydata = (const float*)(Dxy.data + i*Dxy.step);
342 for( j = 0; j < size.width; j++ )
344 double dx = dxdata[j];
345 double dy = dydata[j];
346 dstdata[j] = (float)(factor*(dx*dx*d2ydata[j] + dy*dy*d2xdata[j] - 2*dx*dy*dxydata[j]));
355 cvCornerMinEigenVal( const CvArr* srcarr, CvArr* dstarr,
356 int block_size, int aperture_size )
358 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
360 CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 );
361 cv::cornerMinEigenVal( src, dst, block_size, aperture_size, cv::BORDER_REPLICATE );
365 cvCornerHarris( const CvArr* srcarr, CvArr* dstarr,
366 int block_size, int aperture_size, double k )
368 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
370 CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 );
371 cv::cornerHarris( src, dst, block_size, aperture_size, k, cv::BORDER_REPLICATE );
376 cvCornerEigenValsAndVecs( const void* srcarr, void* dstarr,
377 int block_size, int aperture_size )
379 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
381 CV_Assert( src.rows == dst.rows && src.cols*6 == dst.cols*dst.channels() && dst.depth() == CV_32F );
382 cv::cornerEigenValsAndVecs( src, dst, block_size, aperture_size, cv::BORDER_REPLICATE );
387 cvPreCornerDetect( const void* srcarr, void* dstarr, int aperture_size )
389 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
391 CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 );
392 cv::preCornerDetect( src, dst, aperture_size, cv::BORDER_REPLICATE );