/
tracking.cpp
124 lines (99 loc) · 2.5 KB
/
tracking.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
std::vector<cv::Point2f> trackBead()
{
std::vector<cv::Point2f> resVec;
cv::Mat blurImg, binImg, sdImg;
//cv::Size roiSize(100, 100);
cv::GaussianBlur(copyImg, blurImg, cv::Size(5,5), 0);
maxEntropieThreshold(blurImg, binImg);
std::vector<std::vector<cv::Point> > contours;
cv::findContours(binImg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cv::Point2f tempPt;
for (int ii = 0; ii < contours.size(); ++ii)
{
cv::Rect recBound = cv::boundingRect(contours[ii]);
if ( recBound.width>=5 && recBound.height>=5 )
{
cv::Moments mu = cv::moments(contours[ii], true);
tempPt.x = mu.m10/mu.m00;
tempPt.y = mu.m01/mu.m00;
resVec.push_back(tempPt);
}
}
return resVec;
}
uchar maxEntropieThreshold(const cv::Mat1b& src8, cv::Mat& dst)
{
// Histogram
cv::Mat hist;//(1, 256, 0.0);
/* for (int r=0; r<src8.rows; ++r)
for (int c=0; c<src8.cols; ++c)
hist(src8(r,c))++;
*/
const int histSize[] = {256};
float range[] = {0, 255};
const float* ranges[] = {range};
const int channels[] = {0};
cv::calcHist(&src8,1,channels,cv::Mat(),hist,1,histSize,ranges,true,false);
// Normalize
hist /= double(src8.rows * src8.cols);
// Cumulative histogram
cv::Mat1d cumhist(1, 256, 0.0);
float sum = 0;
for (int i = 0; i < 256; ++i)
{
sum += hist.at<float>(i);
cumhist(i) = sum;
}
cv::Mat1d hl(1, 256, 0.0);
cv::Mat1d hh(1, 256, 0.0);
for (int t = 0; t < 256; ++t)
{
// low range entropy
double cl = cumhist(t);
if (cl > 0)
{
for (int i = 0; i <= t; ++i)
{
if (hist.at<float>(i) > 0)
{
hl(t) = hl(t) - (hist.at<float>(i) / cl) * log(hist.at<float>(i) / cl);
}
}
}
// high range entropy
double ch = 1.0 - cl; // constraint cl + ch = 1
if (ch > 0)
{
for (int i = t+1; i < 256; ++i)
{
if (hist.at<float>(i) > 0)
{
hh(t) = hh(t) - (hist.at<float>(i) / ch) * log(hist.at<float>(i) / ch);
}
}
}
}
// choose best threshold
cv::Mat1d entropie(1, 256, 0.0);
double h_max = hl(0) + hh(0);
uchar threshold = 0;
entropie(0) = h_max;
for (int t = 1; t < 256; ++t)
{
entropie(t) = hl(t) + hh(t);
if (entropie(t) > h_max)
{
h_max = entropie(t);
threshold = uchar(t);
}
}
// Create output image
dst = src8 < threshold;
// Ensure white object on black background
cv::Scalar meanVal = cv::mean(dst);
if (meanVal[0] > 120)
{
cv::bitwise_not(dst, dst);
}
return threshold;
}