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.
43 #include "precomp.hpp"
44 #include "opencl_kernels_imgproc.hpp"
49 static void calcMinEigenVal( const Mat& _cov, Mat& _dst )
52 Size size = _cov.size();
54 volatile bool simd = checkHardwareSupport(CV_CPU_SSE);
57 if( _cov.isContinuous() && _dst.isContinuous() )
59 size.width *= size.height;
63 for( i = 0; i < size.height; i++ )
65 const float* cov = (const float*)(_cov.data + _cov.step*i);
66 float* dst = (float*)(_dst.data + _dst.step*i);
71 __m128 half = _mm_set1_ps(0.5f);
72 for( ; j <= size.width - 5; j += 4 )
74 __m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
75 __m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
76 __m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
77 __m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
79 t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
80 c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
81 b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
82 c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
83 a = _mm_movelh_ps(t, b);
84 b = _mm_movehl_ps(b, t);
85 a = _mm_mul_ps(a, half);
86 c = _mm_mul_ps(c, half);
88 t = _mm_add_ps(_mm_mul_ps(t, t), _mm_mul_ps(b,b));
89 a = _mm_sub_ps(_mm_add_ps(a, c), _mm_sqrt_ps(t));
90 _mm_storeu_ps(dst + j, a);
94 for( ; j < size.width; j++ )
96 float a = cov[j*3]*0.5f;
98 float c = cov[j*3+2]*0.5f;
99 dst[j] = (float)((a + c) - std::sqrt((a - c)*(a - c) + b*b));
105 static void calcHarris( const Mat& _cov, Mat& _dst, double k )
108 Size size = _cov.size();
110 volatile bool simd = checkHardwareSupport(CV_CPU_SSE);
113 if( _cov.isContinuous() && _dst.isContinuous() )
115 size.width *= size.height;
119 for( i = 0; i < size.height; i++ )
121 const float* cov = (const float*)(_cov.data + _cov.step*i);
122 float* dst = (float*)(_dst.data + _dst.step*i);
128 __m128 k4 = _mm_set1_ps((float)k);
129 for( ; j <= size.width - 5; j += 4 )
131 __m128 t0 = _mm_loadu_ps(cov + j*3); // a0 b0 c0 x
132 __m128 t1 = _mm_loadu_ps(cov + j*3 + 3); // a1 b1 c1 x
133 __m128 t2 = _mm_loadu_ps(cov + j*3 + 6); // a2 b2 c2 x
134 __m128 t3 = _mm_loadu_ps(cov + j*3 + 9); // a3 b3 c3 x
136 t = _mm_unpacklo_ps(t0, t1); // a0 a1 b0 b1
137 c = _mm_unpackhi_ps(t0, t1); // c0 c1 x x
138 b = _mm_unpacklo_ps(t2, t3); // a2 a3 b2 b3
139 c = _mm_movelh_ps(c, _mm_unpackhi_ps(t2, t3)); // c0 c1 c2 c3
140 a = _mm_movelh_ps(t, b);
141 b = _mm_movehl_ps(b, t);
142 t = _mm_add_ps(a, c);
143 a = _mm_sub_ps(_mm_mul_ps(a, c), _mm_mul_ps(b, b));
144 t = _mm_mul_ps(_mm_mul_ps(k4, t), t);
145 a = _mm_sub_ps(a, t);
146 _mm_storeu_ps(dst + j, a);
151 for( ; j < size.width; j++ )
154 float b = cov[j*3+1];
155 float c = cov[j*3+2];
156 dst[j] = (float)(a*c - b*b - k*(a + c)*(a + c));
162 static void eigen2x2( const float* cov, float* dst, int n )
164 for( int j = 0; j < n; j++ )
167 double b = cov[j*3+1];
168 double c = cov[j*3+2];
170 double u = (a + c)*0.5;
171 double v = std::sqrt((a - c)*(a - c)*0.25 + b*b);
179 if( e + fabs(y) < 1e-4 )
184 if( e + fabs(y) < 1e-4 )
186 e = 1./(e + fabs(y) + FLT_EPSILON);
191 double d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
192 dst[6*j] = (float)l1;
193 dst[6*j + 2] = (float)(x*d);
194 dst[6*j + 3] = (float)(y*d);
200 if( e + fabs(y) < 1e-4 )
205 if( e + fabs(y) < 1e-4 )
207 e = 1./(e + fabs(y) + FLT_EPSILON);
212 d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
213 dst[6*j + 1] = (float)l2;
214 dst[6*j + 4] = (float)(x*d);
215 dst[6*j + 5] = (float)(y*d);
219 static void calcEigenValsVecs( const Mat& _cov, Mat& _dst )
221 Size size = _cov.size();
222 if( _cov.isContinuous() && _dst.isContinuous() )
224 size.width *= size.height;
228 for( int i = 0; i < size.height; i++ )
230 const float* cov = (const float*)(_cov.data + _cov.step*i);
231 float* dst = (float*)(_dst.data + _dst.step*i);
233 eigen2x2(cov, dst, size.width);
238 enum { MINEIGENVAL=0, HARRIS=1, EIGENVALSVECS=2 };
242 cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
243 int aperture_size, int op_type, double k=0.,
244 int borderType=BORDER_DEFAULT )
246 #ifdef HAVE_TEGRA_OPTIMIZATION
247 if (tegra::cornerEigenValsVecs(src, eigenv, block_size, aperture_size, op_type, k, borderType))
251 int depth = src.depth();
252 double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size;
253 if( aperture_size < 0 )
259 CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 );
262 if( aperture_size > 0 )
264 Sobel( src, Dx, CV_32F, 1, 0, aperture_size, scale, 0, borderType );
265 Sobel( src, Dy, CV_32F, 0, 1, aperture_size, scale, 0, borderType );
269 Scharr( src, Dx, CV_32F, 1, 0, scale, 0, borderType );
270 Scharr( src, Dy, CV_32F, 0, 1, scale, 0, borderType );
273 Size size = src.size();
274 Mat cov( size, CV_32FC3 );
277 for( i = 0; i < size.height; i++ )
279 float* cov_data = (float*)(cov.data + i*cov.step);
280 const float* dxdata = (const float*)(Dx.data + i*Dx.step);
281 const float* dydata = (const float*)(Dy.data + i*Dy.step);
283 for( j = 0; j < size.width; j++ )
285 float dx = dxdata[j];
286 float dy = dydata[j];
288 cov_data[j*3] = dx*dx;
289 cov_data[j*3+1] = dx*dy;
290 cov_data[j*3+2] = dy*dy;
294 boxFilter(cov, cov, cov.depth(), Size(block_size, block_size),
295 Point(-1,-1), false, borderType );
297 if( op_type == MINEIGENVAL )
298 calcMinEigenVal( cov, eigenv );
299 else if( op_type == HARRIS )
300 calcHarris( cov, eigenv, k );
301 else if( op_type == EIGENVALSVECS )
302 calcEigenValsVecs( cov, eigenv );
307 static bool extractCovData(InputArray _src, UMat & Dx, UMat & Dy, int depth,
308 float scale, int aperture_size, int borderType)
310 UMat src = _src.getUMat();
314 src.locateROI(wholeSize, ofs);
316 const int sobel_lsz = 16;
317 if ((aperture_size == 3 || aperture_size == 5 || aperture_size == 7 || aperture_size == -1) &&
318 wholeSize.height > sobel_lsz + (aperture_size >> 1) &&
319 wholeSize.width > sobel_lsz + (aperture_size >> 1))
321 CV_Assert(depth == CV_8U || depth == CV_32F);
323 Dx.create(src.size(), CV_32FC1);
324 Dy.create(src.size(), CV_32FC1);
326 size_t localsize[2] = { sobel_lsz, sobel_lsz };
327 size_t globalsize[2] = { localsize[0] * (1 + (src.cols - 1) / localsize[0]),
328 localsize[1] * (1 + (src.rows - 1) / localsize[1]) };
330 int src_offset_x = (int)((src.offset % src.step) / src.elemSize());
331 int src_offset_y = (int)(src.offset / src.step);
333 const char * const borderTypes[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT",
334 "BORDER_WRAP", "BORDER_REFLECT101" };
336 ocl::Kernel k(format("sobel%d", aperture_size).c_str(), ocl::imgproc::covardata_oclsrc,
337 cv::format("-D BLK_X=%d -D BLK_Y=%d -D %s -D SRCTYPE=%s%s",
338 (int)localsize[0], (int)localsize[1], borderTypes[borderType], ocl::typeToStr(depth),
339 aperture_size < 0 ? " -D SCHARR" : ""));
343 k.args(ocl::KernelArg::PtrReadOnly(src), (int)src.step, src_offset_x, src_offset_y,
344 ocl::KernelArg::WriteOnlyNoSize(Dx), ocl::KernelArg::WriteOnly(Dy),
345 wholeSize.height, wholeSize.width, scale);
347 return k.run(2, globalsize, localsize, false);
351 if (aperture_size > 0)
353 Sobel(_src, Dx, CV_32F, 1, 0, aperture_size, scale, 0, borderType);
354 Sobel(_src, Dy, CV_32F, 0, 1, aperture_size, scale, 0, borderType);
358 Scharr(_src, Dx, CV_32F, 1, 0, scale, 0, borderType);
359 Scharr(_src, Dy, CV_32F, 0, 1, scale, 0, borderType);
366 static bool ocl_cornerMinEigenValVecs(InputArray _src, OutputArray _dst, int block_size,
367 int aperture_size, double k, int borderType, int op_type)
369 CV_Assert(op_type == HARRIS || op_type == MINEIGENVAL);
371 if ( !(borderType == BORDER_CONSTANT || borderType == BORDER_REPLICATE ||
372 borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101) )
375 int type = _src.type(), depth = CV_MAT_DEPTH(type);
376 if ( !(type == CV_8UC1 || type == CV_32FC1) )
379 const char * const borderTypes[] = { "BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT",
380 "BORDER_WRAP", "BORDER_REFLECT101" };
381 const char * const cornerType[] = { "CORNER_MINEIGENVAL", "CORNER_HARRIS", 0 };
384 double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size;
385 if (aperture_size < 0)
392 if (!extractCovData(_src, Dx, Dy, depth, (float)scale, aperture_size, borderType))
395 ocl::Kernel cornelKernel("corner", ocl::imgproc::corner_oclsrc,
396 format("-D anX=%d -D anY=%d -D ksX=%d -D ksY=%d -D %s -D %s",
397 block_size / 2, block_size / 2, block_size, block_size,
398 borderTypes[borderType], cornerType[op_type]));
399 if (cornelKernel.empty())
402 _dst.createSameSize(_src, CV_32FC1);
403 UMat dst = _dst.getUMat();
405 cornelKernel.args(ocl::KernelArg::ReadOnly(Dx), ocl::KernelArg::ReadOnly(Dy),
406 ocl::KernelArg::WriteOnly(dst), (float)k);
408 size_t blockSizeX = 256, blockSizeY = 1;
409 size_t gSize = blockSizeX - block_size / 2 * 2;
410 size_t globalSizeX = (Dx.cols) % gSize == 0 ? Dx.cols / gSize * blockSizeX : (Dx.cols / gSize + 1) * blockSizeX;
411 size_t rows_per_thread = 2;
412 size_t globalSizeY = ((Dx.rows + rows_per_thread - 1) / rows_per_thread) % blockSizeY == 0 ?
413 ((Dx.rows + rows_per_thread - 1) / rows_per_thread) :
414 (((Dx.rows + rows_per_thread - 1) / rows_per_thread) / blockSizeY + 1) * blockSizeY;
416 size_t globalsize[2] = { globalSizeX, globalSizeY }, localsize[2] = { blockSizeX, blockSizeY };
417 return cornelKernel.run(2, globalsize, localsize, false);
420 static bool ocl_preCornerDetect( InputArray _src, OutputArray _dst, int ksize, int borderType, int depth )
422 UMat Dx, Dy, D2x, D2y, Dxy;
424 if (!extractCovData(_src, Dx, Dy, depth, 1, ksize, borderType))
427 Sobel( _src, D2x, CV_32F, 2, 0, ksize, 1, 0, borderType );
428 Sobel( _src, D2y, CV_32F, 0, 2, ksize, 1, 0, borderType );
429 Sobel( _src, Dxy, CV_32F, 1, 1, ksize, 1, 0, borderType );
431 _dst.create( _src.size(), CV_32FC1 );
432 UMat dst = _dst.getUMat();
434 double factor = 1 << (ksize - 1);
437 factor = 1./(factor * factor * factor);
439 ocl::Kernel k("preCornerDetect", ocl::imgproc::precornerdetect_oclsrc);
443 k.args(ocl::KernelArg::ReadOnlyNoSize(Dx), ocl::KernelArg::ReadOnlyNoSize(Dy),
444 ocl::KernelArg::ReadOnlyNoSize(D2x), ocl::KernelArg::ReadOnlyNoSize(D2y),
445 ocl::KernelArg::ReadOnlyNoSize(Dxy), ocl::KernelArg::WriteOnly(dst), (float)factor);
447 size_t globalsize[2] = { dst.cols, dst.rows };
448 return k.run(2, globalsize, NULL, false);
455 void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
457 CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
458 ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, 0.0, borderType, MINEIGENVAL))
460 Mat src = _src.getMat();
461 _dst.create( src.size(), CV_32FC1 );
462 Mat dst = _dst.getMat();
463 #if defined(HAVE_IPP) && (IPP_VERSION_MAJOR >= 8)
464 typedef IppStatus (CV_STDCALL * ippiMinEigenValGetBufferSize)(IppiSize, int, int, int*);
465 typedef IppStatus (CV_STDCALL * ippiMinEigenVal)(const void*, int, Ipp32f*, int, IppiSize, IppiKernelType, int, int, Ipp8u*);
466 IppiKernelType kerType;
470 kerType = ippKernelScharr;
474 kerType = ippKernelSobel;
476 bool isolated = (borderType & BORDER_ISOLATED) != 0;
477 int borderTypeNI = borderType & ~BORDER_ISOLATED;
478 if ((borderTypeNI == BORDER_REPLICATE && (!src.isSubmatrix() || isolated)) &&
479 (kerSize == 3 || kerSize == 5) && (blockSize == 3 || blockSize == 5))
481 ippiMinEigenValGetBufferSize getBufferSizeFunc = 0;
482 ippiMinEigenVal minEigenValFunc = 0;
483 float norm_coef = 0.f;
485 if (src.type() == CV_8UC1)
487 getBufferSizeFunc = (ippiMinEigenValGetBufferSize) ippiMinEigenValGetBufferSize_8u32f_C1R;
488 minEigenValFunc = (ippiMinEigenVal) ippiMinEigenVal_8u32f_C1R;
489 norm_coef = 1.f / 255.f;
490 } else if (src.type() == CV_32FC1)
492 getBufferSizeFunc = (ippiMinEigenValGetBufferSize) ippiMinEigenValGetBufferSize_32f_C1R;
493 minEigenValFunc = (ippiMinEigenVal) ippiMinEigenVal_32f_C1R;
496 norm_coef = kerType == ippKernelSobel ? norm_coef : norm_coef / 2.45f;
498 if (getBufferSizeFunc && minEigenValFunc)
501 IppiSize srcRoi = { src.cols, src.rows };
502 IppStatus ok = getBufferSizeFunc(srcRoi, kerSize, blockSize, &bufferSize);
505 AutoBuffer<uchar> buffer(bufferSize);
506 ok = minEigenValFunc(src.data, (int) src.step, (Ipp32f*) dst.data, (int) dst.step, srcRoi, kerType, kerSize, blockSize, buffer);
507 CV_SUPPRESS_DEPRECATED_START
508 if (ok >= 0) ok = ippiMulC_32f_C1IR(norm_coef, (Ipp32f*) dst.data, (int) dst.step, srcRoi);
509 CV_SUPPRESS_DEPRECATED_END
517 cornerEigenValsVecs( src, dst, blockSize, ksize, MINEIGENVAL, 0, borderType );
520 void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
522 CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
523 ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, k, borderType, HARRIS))
525 Mat src = _src.getMat();
526 _dst.create( src.size(), CV_32FC1 );
527 Mat dst = _dst.getMat();
529 #if IPP_VERSION_X100 >= 801 && 0
530 int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
531 int borderTypeNI = borderType & ~BORDER_ISOLATED;
532 bool isolated = (borderType & BORDER_ISOLATED) != 0;
534 if ( (ksize == 3 || ksize == 5) && (type == CV_8UC1 || type == CV_32FC1) &&
535 (borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE) && cn == 1 && (!src.isSubmatrix() || isolated) )
537 IppiSize roisize = { src.cols, src.rows };
538 IppiMaskSize masksize = ksize == 5 ? ippMskSize5x5 : ippMskSize3x3;
539 IppDataType datatype = type == CV_8UC1 ? ipp8u : ipp32f;
542 double scale = (double)(1 << ((ksize > 0 ? ksize : 3) - 1)) * blockSize;
547 scale = std::pow(scale, -4.0);
549 if (ippiHarrisCornerGetBufferSize(roisize, masksize, blockSize, datatype, cn, &bufsize) >= 0)
551 Ipp8u * buffer = ippsMalloc_8u(bufsize);
552 IppiDifferentialKernel filterType = ksize > 0 ? ippFilterSobel : ippFilterScharr;
553 IppiBorderType borderTypeIpp = borderTypeNI == BORDER_CONSTANT ? ippBorderConst : ippBorderRepl;
554 IppStatus status = (IppStatus)-1;
557 status = ippiHarrisCorner_8u32f_C1R((const Ipp8u *)src.data, (int)src.step, (Ipp32f *)dst.data, (int)dst.step, roisize,
558 filterType, masksize, blockSize, (Ipp32f)k, (Ipp32f)scale, borderTypeIpp, 0, buffer);
559 else if (depth == CV_32F)
560 status = ippiHarrisCorner_32f_C1R((const Ipp32f *)src.data, (int)src.step, (Ipp32f *)dst.data, (int)dst.step, roisize,
561 filterType, masksize, blockSize, (Ipp32f)k, (Ipp32f)scale, borderTypeIpp, 0, buffer);
571 cornerEigenValsVecs( src, dst, blockSize, ksize, HARRIS, k, borderType );
575 void cv::cornerEigenValsAndVecs( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
577 Mat src = _src.getMat();
578 Size dsz = _dst.size();
579 int dtype = _dst.type();
581 if( dsz.height != src.rows || dsz.width*CV_MAT_CN(dtype) != src.cols*6 || CV_MAT_DEPTH(dtype) != CV_32F )
582 _dst.create( src.size(), CV_32FC(6) );
583 Mat dst = _dst.getMat();
584 cornerEigenValsVecs( src, dst, blockSize, ksize, EIGENVALSVECS, 0, borderType );
588 void cv::preCornerDetect( InputArray _src, OutputArray _dst, int ksize, int borderType )
590 int type = _src.type();
591 CV_Assert( type == CV_8UC1 || type == CV_32FC1 );
593 CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat(),
594 ocl_preCornerDetect(_src, _dst, ksize, borderType, CV_MAT_DEPTH(type)))
596 Mat Dx, Dy, D2x, D2y, Dxy, src = _src.getMat();
597 _dst.create( src.size(), CV_32FC1 );
598 Mat dst = _dst.getMat();
600 Sobel( src, Dx, CV_32F, 1, 0, ksize, 1, 0, borderType );
601 Sobel( src, Dy, CV_32F, 0, 1, ksize, 1, 0, borderType );
602 Sobel( src, D2x, CV_32F, 2, 0, ksize, 1, 0, borderType );
603 Sobel( src, D2y, CV_32F, 0, 2, ksize, 1, 0, borderType );
604 Sobel( src, Dxy, CV_32F, 1, 1, ksize, 1, 0, borderType );
606 double factor = 1 << (ksize - 1);
607 if( src.depth() == CV_8U )
609 factor = 1./(factor * factor * factor);
612 volatile bool haveSSE2 = cv::checkHardwareSupport(CV_CPU_SSE2);
613 __m128 v_factor = _mm_set1_ps((float)factor), v_m2 = _mm_set1_ps(-2.0f);
616 Size size = src.size();
618 for( i = 0; i < size.height; i++ )
620 float* dstdata = (float*)(dst.data + i*dst.step);
621 const float* dxdata = (const float*)(Dx.data + i*Dx.step);
622 const float* dydata = (const float*)(Dy.data + i*Dy.step);
623 const float* d2xdata = (const float*)(D2x.data + i*D2x.step);
624 const float* d2ydata = (const float*)(D2y.data + i*D2y.step);
625 const float* dxydata = (const float*)(Dxy.data + i*Dxy.step);
632 for( ; j <= size.width - 4; j += 4 )
634 __m128 v_dx = _mm_loadu_ps((const float *)(dxdata + j));
635 __m128 v_dy = _mm_loadu_ps((const float *)(dydata + j));
637 __m128 v_s1 = _mm_mul_ps(_mm_mul_ps(v_dx, v_dx), _mm_loadu_ps((const float *)(d2ydata + j)));
638 __m128 v_s2 = _mm_mul_ps(_mm_mul_ps(v_dy, v_dy), _mm_loadu_ps((const float *)(d2xdata + j)));
639 __m128 v_s3 = _mm_mul_ps(_mm_mul_ps(v_dx, v_dy), _mm_loadu_ps((const float *)(dxydata + j)));
640 v_s1 = _mm_mul_ps(v_factor, _mm_add_ps(v_s1, _mm_add_ps(v_s2, _mm_mul_ps(v_s3, v_m2))));
641 _mm_storeu_ps(dstdata + j, v_s1);
646 for( ; j < size.width; j++ )
648 float dx = dxdata[j];
649 float dy = dydata[j];
650 dstdata[j] = (float)(factor*(dx*dx*d2ydata[j] + dy*dy*d2xdata[j] - 2*dx*dy*dxydata[j]));
656 cvCornerMinEigenVal( const CvArr* srcarr, CvArr* dstarr,
657 int block_size, int aperture_size )
659 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
661 CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 );
662 cv::cornerMinEigenVal( src, dst, block_size, aperture_size, cv::BORDER_REPLICATE );
666 cvCornerHarris( const CvArr* srcarr, CvArr* dstarr,
667 int block_size, int aperture_size, double k )
669 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
671 CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 );
672 cv::cornerHarris( src, dst, block_size, aperture_size, k, cv::BORDER_REPLICATE );
677 cvCornerEigenValsAndVecs( const void* srcarr, void* dstarr,
678 int block_size, int aperture_size )
680 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
682 CV_Assert( src.rows == dst.rows && src.cols*6 == dst.cols*dst.channels() && dst.depth() == CV_32F );
683 cv::cornerEigenValsAndVecs( src, dst, block_size, aperture_size, cv::BORDER_REPLICATE );
688 cvPreCornerDetect( const void* srcarr, void* dstarr, int aperture_size )
690 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
692 CV_Assert( src.size() == dst.size() && dst.type() == CV_32FC1 );
693 cv::preCornerDetect( src, dst, aperture_size, cv::BORDER_REPLICATE );