Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
724 lines
18 KiB
724 lines
18 KiB
/*M/////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
|
// |
|
// By downloading, copying, installing or using the software you agree to this license. |
|
// If you do not agree to this license, do not download, install, copy or use the software. |
|
// |
|
// Copyright (C) 2009, Farhad Dadgostar |
|
// Intel Corporation and third party copyrights are property of their respective owners. |
|
// |
|
// Redistribution and use in source and binary forms, with or without modification, |
|
// are permitted provided that the following conditions are met: |
|
// |
|
// * Redistribution's of source code must retain the above copyright notice, |
|
// this list of conditions and the following disclaimer. |
|
// |
|
// * Redistribution's in binary form must reproduce the above copyright notice, |
|
// this list of conditions and the following disclaimer in the documentation |
|
// and/or other materials provided with the distribution. |
|
// |
|
// * The name of Intel Corporation may not be used to endorse or promote products |
|
// derived from this software without specific prior written permission. |
|
// |
|
// This software is provided by the copyright holders and contributors "as is" and |
|
// any express or implied warranties, including, but not limited to, the implied |
|
// warranties of merchantability and fitness for a particular purpose are disclaimed. |
|
// In no event shall the Intel Corporation or contributors be liable for any direct, |
|
// indirect, incidental, special, exemplary, or consequential damages |
|
// (including, but not limited to, procurement of substitute goods or services; |
|
// loss of use, data, or profits; or business interruption) however caused |
|
// and on any theory of liability, whether in contract, strict liability, |
|
// or tort (including negligence or otherwise) arising in any way out of |
|
// the use of this software, even if advised of the possibility of such damage. |
|
// |
|
//M*/ |
|
|
|
#include "precomp.hpp" |
|
#include "opencv2/contrib/compat.hpp" |
|
|
|
CvFuzzyPoint::CvFuzzyPoint(double _x, double _y) |
|
{ |
|
x = _x; |
|
y = _y; |
|
}; |
|
|
|
bool CvFuzzyCurve::between(double x, double x1, double x2) |
|
{ |
|
if ((x >= x1) && (x <= x2)) |
|
return true; |
|
else if ((x >= x2) && (x <= x1)) |
|
return true; |
|
|
|
return false; |
|
}; |
|
|
|
CvFuzzyCurve::CvFuzzyCurve() |
|
{ |
|
value = 0; |
|
}; |
|
|
|
CvFuzzyCurve::~CvFuzzyCurve() |
|
{ |
|
// nothing to do |
|
}; |
|
|
|
void CvFuzzyCurve::setCentre(double _centre) |
|
{ |
|
centre = _centre; |
|
}; |
|
|
|
double CvFuzzyCurve::getCentre() |
|
{ |
|
return centre; |
|
}; |
|
|
|
void CvFuzzyCurve::clear() |
|
{ |
|
points.clear(); |
|
}; |
|
|
|
void CvFuzzyCurve::addPoint(double x, double y) |
|
{ |
|
CvFuzzyPoint *point; |
|
point = new CvFuzzyPoint(x, y); |
|
points.push_back(*point); |
|
}; |
|
|
|
double CvFuzzyCurve::calcValue(double param) |
|
{ |
|
int size = (int)points.size(); |
|
double x1, y1, x2, y2, m, y; |
|
for (int i = 1; i < size; i++) |
|
{ |
|
x1 = points[i-1].x; |
|
x2 = points[i].x; |
|
if (between(param, x1, x2)) { |
|
y1 = points[i-1].y; |
|
y2 = points[i].y; |
|
if (x2 == x1) |
|
return y2; |
|
m = (y2-y1)/(x2-x1); |
|
y = m*(param-x1)+y1; |
|
return y; |
|
} |
|
} |
|
return 0; |
|
}; |
|
|
|
double CvFuzzyCurve::getValue() |
|
{ |
|
return value; |
|
}; |
|
|
|
void CvFuzzyCurve::setValue(double _value) |
|
{ |
|
value = _value; |
|
}; |
|
|
|
|
|
CvFuzzyFunction::CvFuzzyFunction() |
|
{ |
|
// nothing to do |
|
}; |
|
|
|
CvFuzzyFunction::~CvFuzzyFunction() |
|
{ |
|
curves.clear(); |
|
}; |
|
|
|
void CvFuzzyFunction::addCurve(CvFuzzyCurve *curve, double value) |
|
{ |
|
curves.push_back(*curve); |
|
curve->setValue(value); |
|
}; |
|
|
|
void CvFuzzyFunction::resetValues() |
|
{ |
|
int numCurves = (int)curves.size(); |
|
for (int i = 0; i < numCurves; i++) |
|
curves[i].setValue(0); |
|
}; |
|
|
|
double CvFuzzyFunction::calcValue() |
|
{ |
|
double s1 = 0, s2 = 0, v; |
|
int numCurves = (int)curves.size(); |
|
for (int i = 0; i < numCurves; i++) |
|
{ |
|
v = curves[i].getValue(); |
|
s1 += curves[i].getCentre() * v; |
|
s2 += v; |
|
} |
|
|
|
if (s2 != 0) |
|
return s1/s2; |
|
else |
|
return 0; |
|
}; |
|
|
|
CvFuzzyCurve *CvFuzzyFunction::newCurve() |
|
{ |
|
CvFuzzyCurve *c; |
|
c = new CvFuzzyCurve(); |
|
addCurve(c); |
|
return c; |
|
}; |
|
|
|
CvFuzzyRule::CvFuzzyRule() |
|
{ |
|
fuzzyInput1 = NULL; |
|
fuzzyInput2 = NULL; |
|
fuzzyOutput = NULL; |
|
}; |
|
|
|
CvFuzzyRule::~CvFuzzyRule() |
|
{ |
|
if (fuzzyInput1 != NULL) |
|
delete fuzzyInput1; |
|
|
|
if (fuzzyInput2 != NULL) |
|
delete fuzzyInput2; |
|
|
|
if (fuzzyOutput != NULL) |
|
delete fuzzyOutput; |
|
}; |
|
|
|
void CvFuzzyRule::setRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1) |
|
{ |
|
fuzzyInput1 = c1; |
|
fuzzyInput2 = c2; |
|
fuzzyOutput = o1; |
|
}; |
|
|
|
double CvFuzzyRule::calcValue(double param1, double param2) |
|
{ |
|
double v1, v2; |
|
v1 = fuzzyInput1->calcValue(param1); |
|
if (fuzzyInput2 != NULL) |
|
{ |
|
v2 = fuzzyInput2->calcValue(param2); |
|
if (v1 < v2) |
|
return v1; |
|
else |
|
return v2; |
|
} |
|
else |
|
return v1; |
|
}; |
|
|
|
CvFuzzyCurve *CvFuzzyRule::getOutputCurve() |
|
{ |
|
return fuzzyOutput; |
|
}; |
|
|
|
CvFuzzyController::CvFuzzyController() |
|
{ |
|
// nothing to do |
|
}; |
|
|
|
CvFuzzyController::~CvFuzzyController() |
|
{ |
|
int size = (int)rules.size(); |
|
for(int i = 0; i < size; i++) |
|
delete rules[i]; |
|
}; |
|
|
|
void CvFuzzyController::addRule(CvFuzzyCurve *c1, CvFuzzyCurve *c2, CvFuzzyCurve *o1) |
|
{ |
|
CvFuzzyRule *f = new CvFuzzyRule(); |
|
rules.push_back(f); |
|
f->setRule(c1, c2, o1); |
|
}; |
|
|
|
double CvFuzzyController::calcOutput(double param1, double param2) |
|
{ |
|
double v; |
|
CvFuzzyFunction list; |
|
int size = (int)rules.size(); |
|
|
|
for(int i = 0; i < size; i++) |
|
{ |
|
v = rules[i]->calcValue(param1, param2); |
|
if (v != 0) |
|
list.addCurve(rules[i]->getOutputCurve(), v); |
|
} |
|
v = list.calcValue(); |
|
return v; |
|
}; |
|
|
|
CvFuzzyMeanShiftTracker::FuzzyResizer::FuzzyResizer() |
|
{ |
|
CvFuzzyCurve *i1L, *i1M, *i1H; |
|
CvFuzzyCurve *oS, *oZE, *oE; |
|
CvFuzzyCurve *c; |
|
|
|
double MedStart = 0.1, MedWidth = 0.15; |
|
|
|
c = iInput.newCurve(); |
|
c->addPoint(0, 1); |
|
c->addPoint(0.1, 0); |
|
c->setCentre(0); |
|
i1L = c; |
|
|
|
c = iInput.newCurve(); |
|
c->addPoint(0.05, 0); |
|
c->addPoint(MedStart, 1); |
|
c->addPoint(MedStart+MedWidth, 1); |
|
c->addPoint(MedStart+MedWidth+0.05, 0); |
|
c->setCentre(MedStart+(MedWidth/2)); |
|
i1M = c; |
|
|
|
c = iInput.newCurve(); |
|
c->addPoint(MedStart+MedWidth, 0); |
|
c->addPoint(1, 1); |
|
c->addPoint(1000, 1); |
|
c->setCentre(1); |
|
i1H = c; |
|
|
|
c = iOutput.newCurve(); |
|
c->addPoint(-10000, 1); |
|
c->addPoint(-5, 1); |
|
c->addPoint(-0.5, 0); |
|
c->setCentre(-5); |
|
oS = c; |
|
|
|
c = iOutput.newCurve(); |
|
c->addPoint(-1, 0); |
|
c->addPoint(-0.05, 1); |
|
c->addPoint(0.05, 1); |
|
c->addPoint(1, 0); |
|
c->setCentre(0); |
|
oZE = c; |
|
|
|
c = iOutput.newCurve(); |
|
c->addPoint(-0.5, 0); |
|
c->addPoint(5, 1); |
|
c->addPoint(1000, 1); |
|
c->setCentre(5); |
|
oE = c; |
|
|
|
fuzzyController.addRule(i1L, NULL, oS); |
|
fuzzyController.addRule(i1M, NULL, oZE); |
|
fuzzyController.addRule(i1H, NULL, oE); |
|
}; |
|
|
|
int CvFuzzyMeanShiftTracker::FuzzyResizer::calcOutput(double edgeDensity, double density) |
|
{ |
|
return (int)fuzzyController.calcOutput(edgeDensity, density); |
|
}; |
|
|
|
CvFuzzyMeanShiftTracker::SearchWindow::SearchWindow() |
|
{ |
|
x = 0; |
|
y = 0; |
|
width = 0; |
|
height = 0; |
|
maxWidth = 0; |
|
maxHeight = 0; |
|
xGc = 0; |
|
yGc = 0; |
|
m00 = 0; |
|
m01 = 0; |
|
m10 = 0; |
|
m11 = 0; |
|
m02 = 0; |
|
m20 = 0; |
|
ellipseHeight = 0; |
|
ellipseWidth = 0; |
|
ellipseAngle = 0; |
|
density = 0; |
|
depthLow = 0; |
|
depthHigh = 0; |
|
fuzzyResizer = NULL; |
|
}; |
|
|
|
CvFuzzyMeanShiftTracker::SearchWindow::~SearchWindow() |
|
{ |
|
if (fuzzyResizer != NULL) |
|
delete fuzzyResizer; |
|
} |
|
|
|
void CvFuzzyMeanShiftTracker::SearchWindow::setSize(int _x, int _y, int _width, int _height) |
|
{ |
|
x = _x; |
|
y = _y; |
|
width = _width; |
|
height = _height; |
|
|
|
if (x < 0) |
|
x = 0; |
|
|
|
if (y < 0) |
|
y = 0; |
|
|
|
if (x + width > maxWidth) |
|
width = maxWidth - x; |
|
|
|
if (y + height > maxHeight) |
|
height = maxHeight - y; |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::SearchWindow::initDepthValues(IplImage *maskImage, IplImage *depthMap) |
|
{ |
|
unsigned int d=0, mind = 0xFFFF, maxd = 0, m0 = 0, m1 = 0, mc, dd; |
|
unsigned char *data = NULL; |
|
unsigned short *depthData = NULL; |
|
|
|
for (int j = 0; j < height; j++) |
|
{ |
|
data = (unsigned char *)(maskImage->imageData + (maskImage->widthStep * (j + y)) + x); |
|
if (depthMap) |
|
depthData = (unsigned short *)(depthMap->imageData + (depthMap->widthStep * (j + y)) + x); |
|
|
|
for (int i = 0; i < width; i++) |
|
{ |
|
if (*data) |
|
{ |
|
m0 += 1; |
|
|
|
if (depthData) |
|
{ |
|
if (*depthData) |
|
{ |
|
d = *depthData; |
|
m1 += d; |
|
if (d < mind) |
|
mind = d; |
|
if (d > maxd) |
|
maxd = d; |
|
} |
|
depthData++; |
|
} |
|
} |
|
data++; |
|
} |
|
} |
|
|
|
if (m0 > 0) |
|
{ |
|
mc = m1/m0; |
|
if ((mc - mind) > (maxd - mc)) |
|
dd = maxd - mc; |
|
else |
|
dd = mc - mind; |
|
dd = dd - dd/10; |
|
depthHigh = mc + dd; |
|
depthLow = mc - dd; |
|
} |
|
else |
|
{ |
|
depthHigh = 32000; |
|
depthLow = 0; |
|
} |
|
}; |
|
|
|
bool CvFuzzyMeanShiftTracker::SearchWindow::shift() |
|
{ |
|
if ((xGc != (width/2)) || (yGc != (height/2))) |
|
{ |
|
setSize(x + (xGc-(width/2)), y + (yGc-(height/2)), width, height); |
|
return true; |
|
} |
|
else |
|
{ |
|
return false; |
|
} |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::SearchWindow::extractInfo(IplImage *maskImage, IplImage *depthMap, bool initDepth) |
|
{ |
|
m00 = 0; |
|
m10 = 0; |
|
m01 = 0; |
|
m11 = 0; |
|
density = 0; |
|
m02 = 0; |
|
m20 = 0; |
|
ellipseHeight = 0; |
|
ellipseWidth = 0; |
|
|
|
maxWidth = maskImage->width; |
|
maxHeight = maskImage->height; |
|
|
|
if (initDepth) |
|
initDepthValues(maskImage, depthMap); |
|
|
|
unsigned char *maskData = NULL; |
|
unsigned short *depthData = NULL, depth; |
|
bool isOk; |
|
unsigned long count; |
|
|
|
verticalEdgeLeft = 0; |
|
verticalEdgeRight = 0; |
|
horizontalEdgeTop = 0; |
|
horizontalEdgeBottom = 0; |
|
|
|
for (int j = 0; j < height; j++) |
|
{ |
|
maskData = (unsigned char *)(maskImage->imageData + (maskImage->widthStep * (j + y)) + x); |
|
if (depthMap) |
|
depthData = (unsigned short *)(depthMap->imageData + (depthMap->widthStep * (j + y)) + x); |
|
|
|
count = 0; |
|
for (int i = 0; i < width; i++) |
|
{ |
|
if (*maskData) |
|
{ |
|
isOk = true; |
|
if (depthData) |
|
{ |
|
depth = (*depthData); |
|
if ((depth > depthHigh) || (depth < depthLow)) |
|
isOk = false; |
|
|
|
depthData++; |
|
} |
|
|
|
if (isOk) |
|
{ |
|
m00++; |
|
m01 += j; |
|
m10 += i; |
|
m02 += (j * j); |
|
m20 += (i * i); |
|
m11 += (j * i); |
|
|
|
if (i == 0) |
|
verticalEdgeLeft++; |
|
else if (i == width-1) |
|
verticalEdgeRight++; |
|
else if (j == 0) |
|
horizontalEdgeTop++; |
|
else if (j == height-1) |
|
horizontalEdgeBottom++; |
|
|
|
count++; |
|
} |
|
} |
|
maskData++; |
|
} |
|
} |
|
|
|
if (m00 > 0) |
|
{ |
|
xGc = (m10 / m00); |
|
yGc = (m01 / m00); |
|
|
|
double a, b, c, e1, e2, e3; |
|
a = ((double)m20/(double)m00)-(xGc * xGc); |
|
b = 2*(((double)m11/(double)m00)-(xGc * yGc)); |
|
c = ((double)m02/(double)m00)-(yGc * yGc); |
|
e1 = a+c; |
|
e3 = a-c; |
|
e2 = sqrt((b*b)+(e3*e3)); |
|
ellipseHeight = int(sqrt(0.5*(e1+e2))); |
|
ellipseWidth = int(sqrt(0.5*(e1-e2))); |
|
if (e3 == 0) |
|
ellipseAngle = 0; |
|
else |
|
ellipseAngle = 0.5*atan(b/e3); |
|
|
|
density = (double)m00/(double)(width * height); |
|
} |
|
else |
|
{ |
|
xGc = width / 2; |
|
yGc = height / 2; |
|
ellipseHeight = 0; |
|
ellipseWidth = 0; |
|
ellipseAngle = 0; |
|
density = 0; |
|
} |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsEdgeDensityLinear(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh) { |
|
int x1 = horizontalEdgeTop; |
|
int x2 = horizontalEdgeBottom; |
|
int y1 = verticalEdgeLeft; |
|
int y2 = verticalEdgeRight; |
|
int gx = (width*2)/5; |
|
int gy = (height*2)/5; |
|
int lx = width/10; |
|
int ly = height/10; |
|
|
|
resizeDy = 0; |
|
resizeDh = 0; |
|
resizeDx = 0; |
|
resizeDw = 0; |
|
|
|
if (x1 > gx) { |
|
resizeDy = -1; |
|
} else if (x1 < lx) { |
|
resizeDy = +1; |
|
} |
|
|
|
if (x2 > gx) { |
|
resizeDh = resizeDy + 1; |
|
} else if (x2 < lx) { |
|
resizeDh = - (resizeDy + 1); |
|
} else { |
|
resizeDh = - resizeDy; |
|
} |
|
|
|
if (y1 > gy) { |
|
resizeDx = -1; |
|
} else if (y1 < ly) { |
|
resizeDx = +1; |
|
} |
|
|
|
if (y2 > gy) { |
|
resizeDw = resizeDx + 1; |
|
} else if (y2 < ly) { |
|
resizeDw = - (resizeDx + 1); |
|
} else { |
|
resizeDw = - resizeDx; |
|
} |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsInnerDensity(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh) |
|
{ |
|
int newWidth, newHeight, dx, dy; |
|
double px, py; |
|
newWidth = int(sqrt(double(m00)*1.3)); |
|
newHeight = int(newWidth*1.2); |
|
dx = (newWidth - width); |
|
dy = (newHeight - height); |
|
px = (double)xGc/(double)width; |
|
py = (double)yGc/(double)height; |
|
resizeDx = (int)(px*dx); |
|
resizeDy = (int)(py*dy); |
|
resizeDw = (int)((1-px)*dx); |
|
resizeDh = (int)((1-py)*dy); |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::SearchWindow::getResizeAttribsEdgeDensityFuzzy(int &resizeDx, int &resizeDy, int &resizeDw, int &resizeDh) |
|
{ |
|
double dx1=0, dx2, dy1, dy2; |
|
|
|
resizeDy = 0; |
|
resizeDh = 0; |
|
resizeDx = 0; |
|
resizeDw = 0; |
|
|
|
if (fuzzyResizer == NULL) |
|
fuzzyResizer = new FuzzyResizer(); |
|
|
|
dx2 = fuzzyResizer->calcOutput(double(verticalEdgeRight)/double(height), density); |
|
if (dx1 == dx2) |
|
{ |
|
resizeDx = int(-dx1); |
|
resizeDw = int(dx1+dx2); |
|
} |
|
|
|
dy1 = fuzzyResizer->calcOutput(double(horizontalEdgeTop)/double(width), density); |
|
dy2 = fuzzyResizer->calcOutput(double(horizontalEdgeBottom)/double(width), density); |
|
|
|
dx1 = fuzzyResizer->calcOutput(double(verticalEdgeLeft)/double(height), density); |
|
dx2 = fuzzyResizer->calcOutput(double(verticalEdgeRight)/double(height), density); |
|
//if (dx1 == dx2) |
|
{ |
|
resizeDx = int(-dx1); |
|
resizeDw = int(dx1+dx2); |
|
} |
|
|
|
dy1 = fuzzyResizer->calcOutput(double(horizontalEdgeTop)/double(width), density); |
|
dy2 = fuzzyResizer->calcOutput(double(horizontalEdgeBottom)/double(width), density); |
|
//if (dy1 == dy2) |
|
{ |
|
resizeDy = int(-dy1); |
|
resizeDh = int(dy1+dy2); |
|
} |
|
}; |
|
|
|
bool CvFuzzyMeanShiftTracker::SearchWindow::meanShift(IplImage *maskImage, IplImage *depthMap, int maxIteration, bool initDepth) |
|
{ |
|
numShifts = 0; |
|
do |
|
{ |
|
extractInfo(maskImage, depthMap, initDepth); |
|
if (! shift()) |
|
return true; |
|
} while (++numShifts < maxIteration); |
|
|
|
return false; |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::findOptimumSearchWindow(SearchWindow &searchWindow, IplImage *maskImage, IplImage *depthMap, int maxIteration, int resizeMethod, bool initDepth) |
|
{ |
|
int resizeDx, resizeDy, resizeDw, resizeDh; |
|
resizeDx = 0; |
|
resizeDy = 0; |
|
resizeDw = 0; |
|
resizeDh = 0; |
|
searchWindow.numIters = 0; |
|
for (int i = 0; i < maxIteration; i++) |
|
{ |
|
searchWindow.numIters++; |
|
searchWindow.meanShift(maskImage, depthMap, MaxMeanShiftIteration, initDepth); |
|
switch (resizeMethod) |
|
{ |
|
case rmEdgeDensityLinear : |
|
searchWindow.getResizeAttribsEdgeDensityLinear(resizeDx, resizeDy, resizeDw, resizeDh); |
|
break; |
|
case rmEdgeDensityFuzzy : |
|
//searchWindow.getResizeAttribsEdgeDensityLinear(resizeDx, resizeDy, resizeDw, resizeDh); |
|
searchWindow.getResizeAttribsEdgeDensityFuzzy(resizeDx, resizeDy, resizeDw, resizeDh); |
|
break; |
|
case rmInnerDensity : |
|
searchWindow.getResizeAttribsInnerDensity(resizeDx, resizeDy, resizeDw, resizeDh); |
|
break; |
|
default: |
|
searchWindow.getResizeAttribsEdgeDensityLinear(resizeDx, resizeDy, resizeDw, resizeDh); |
|
} |
|
|
|
searchWindow.ldx = resizeDx; |
|
searchWindow.ldy = resizeDy; |
|
searchWindow.ldw = resizeDw; |
|
searchWindow.ldh = resizeDh; |
|
|
|
if ((resizeDx == 0) && (resizeDy == 0) && (resizeDw == 0) && (resizeDh == 0)) |
|
break; |
|
|
|
searchWindow.setSize(searchWindow.x + resizeDx, searchWindow.y + resizeDy, searchWindow.width + resizeDw, searchWindow.height + resizeDh); |
|
} |
|
}; |
|
|
|
CvFuzzyMeanShiftTracker::CvFuzzyMeanShiftTracker() |
|
{ |
|
searchMode = tsSetWindow; |
|
}; |
|
|
|
CvFuzzyMeanShiftTracker::~CvFuzzyMeanShiftTracker() |
|
{ |
|
// nothing to do |
|
}; |
|
|
|
void CvFuzzyMeanShiftTracker::track(IplImage *maskImage, IplImage *depthMap, int resizeMethod, bool resetSearch, int minKernelMass) |
|
{ |
|
bool initDepth = false; |
|
|
|
if (resetSearch) |
|
searchMode = tsSetWindow; |
|
|
|
switch (searchMode) |
|
{ |
|
case tsDisabled: |
|
return; |
|
case tsSearching: |
|
return; |
|
case tsSetWindow: |
|
kernel.maxWidth = maskImage->width; |
|
kernel.maxHeight = maskImage->height; |
|
kernel.setSize(0, 0, maskImage->width, maskImage->height); |
|
initDepth = true; |
|
case tsTracking: |
|
searchMode = tsSearching; |
|
findOptimumSearchWindow(kernel, maskImage, depthMap, MaxSetSizeIteration, resizeMethod, initDepth); |
|
if ((kernel.density == 0) || (kernel.m00 < minKernelMass)) |
|
searchMode = tsSetWindow; |
|
else |
|
searchMode = tsTracking; |
|
} |
|
}; |
|
|
|
|