Skip to content

Commit 0c5a8e1

Browse files
committed
tracking: speedup NCC kernel for TLD and Median Flow
1 parent 941865c commit 0c5a8e1

File tree

1 file changed

+56
-10
lines changed

1 file changed

+56
-10
lines changed

modules/tracking/src/tracking_utils.cpp

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,62 @@ using namespace cv;
88

99
double tracking_internal::computeNCC(const Mat& patch1, const Mat& patch2)
1010
{
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);
1313

1414
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+
}
2369
}

0 commit comments

Comments
 (0)