@@ -8,16 +8,62 @@ using namespace cv;
8
8
9
9
double tracking_internal::computeNCC (const Mat& patch1, const Mat& patch2)
10
10
{
11
- CV_Assert ( patch1.rows == patch2.rows );
12
- CV_Assert ( patch1.cols == patch2.cols );
11
+ CV_Assert ( patch1.rows == patch2.rows ,
12
+ patch1.cols == patch2.cols );
13
13
14
14
int N = patch1.rows * patch1.cols ;
15
- double s1 = sum (patch1)(0 );
16
- double s2 = sum (patch2)(0 );
17
- double n1 = norm (patch1, NORM_L2SQR);
18
- double n2 = norm (patch2, NORM_L2SQR);
19
- double prod=patch1.dot (patch2);
20
- double sq1 = sqrt (std::max (0.0 , n1 - 1.0 * s1 * s1 / N));
21
- double sq2 = sqrt (std::max (0.0 , n2 - 1.0 * s2 * s2 / N));
22
- return (sq2 == 0 ) ? sq1 / abs (sq1) : (prod - s1 * s2 / N) / sq1 / sq2;
15
+
16
+ if (N <= 1000 && patch1.type () == CV_8U && patch2.type () == CV_8U)
17
+ {
18
+ unsigned s1 = 0 , s2 = 0 ;
19
+ unsigned n1 = 0 , n2 = 0 ;
20
+ unsigned prod = 0 ;
21
+
22
+ if (patch1.isContinuous () && patch2.isContinuous ())
23
+ {
24
+ const uchar* p1Ptr = patch1.ptr <uchar>(0 );
25
+ const uchar* p2Ptr = patch2.ptr <uchar>(0 );
26
+
27
+ for (int j = 0 ; j < N; j++)
28
+ {
29
+ s1 += p1Ptr[j];
30
+ s2 += p2Ptr[j];
31
+ n1 += p1Ptr[j]*p1Ptr[j];
32
+ n2 += p2Ptr[j]*p2Ptr[j];
33
+ prod += p1Ptr[j]*p2Ptr[j];
34
+ }
35
+ }
36
+ else
37
+ {
38
+ for (int i = 0 ; i < patch1.rows ; i++)
39
+ {
40
+ const uchar* p1Ptr = patch1.ptr <uchar>(i);
41
+ const uchar* p2Ptr = patch2.ptr <uchar>(i);
42
+
43
+ for (int j = 0 ; j < patch1.cols ; j++)
44
+ {
45
+ s1 += p1Ptr[j];
46
+ s2 += p2Ptr[j];
47
+ n1 += p1Ptr[j]*p1Ptr[j];
48
+ n2 += p2Ptr[j]*p2Ptr[j];
49
+ prod += p1Ptr[j]*p2Ptr[j];
50
+ }
51
+ }
52
+ }
53
+
54
+ double sq1 = sqrt (std::max (0.0 , n1 - 1.0 * s1 * s1 / N));
55
+ double sq2 = sqrt (std::max (0.0 , n2 - 1.0 * s2 * s2 / N));
56
+ return (sq2 == 0 ) ? sq1 / abs (sq1) : (prod - 1.0 * s1 * s2 / N) / sq1 / sq2;
57
+ }
58
+ else
59
+ {
60
+ double s1 = sum (patch1)(0 );
61
+ double s2 = sum (patch2)(0 );
62
+ double n1 = norm (patch1, NORM_L2SQR);
63
+ double n2 = norm (patch2, NORM_L2SQR);
64
+ double prod=patch1.dot (patch2);
65
+ double sq1 = sqrt (std::max (0.0 , n1 - 1.0 * s1 * s1 / N));
66
+ double sq2 = sqrt (std::max (0.0 , n2 - 1.0 * s2 * s2 / N));
67
+ return (sq2 == 0 ) ? sq1 / abs (sq1) : (prod - s1 * s2 / N) / sq1 / sq2;
68
+ }
23
69
}
0 commit comments