该类是OPENCV中的一个类。
类PatchGenerator的声明位于legacy.hpp中;
class CV_EXPORTS PatchGenerator
{
public:
PatchGenerator();
PatchGenerator(double _backgroundMin, double _backgroundMax,
double _noiseRange, bool _randomBlur=true,
double _lambdaMin=0.6, double _lambdaMax=1.5,
double _thetaMin=-CV_PI, double _thetaMax=CV_PI,
double _phiMin=-CV_PI, double _phiMax=CV_PI);
void operator()(const Mat&image, Point2f pt, Mat& patch, Size patchSize, RNG& rng) const;
void operator()(const Mat& image, const Mat& transform, Mat& patch,
SizepatchSize, RNG& rng) const;
void warpWholeImage(const Mat& image, Mat& matT, Mat&buf,
CV_OUTMat& warped, int border, RNG& rng) const;
void generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
CV_OUTMat& transform, RNG& rng,
bool inverse=false) const;
void setAffineParam(double lambda, double theta, double phi);
...
};
类PatchGenerator的实现位于planardetect.cpp中
void PatchGenerator::operator ()(const Mat& image, Point2f pt, Mat&patch, Size patchSize, RNG& rng) const
{
double buffer[6];
Mat_<double> T(2, 3, buffer);//定义仿射矩阵
generateRandomTransform(pt,Point2f((patchSize.width-1)*0.5f, (patchSize.height-1)*0.5f), T, rng);//按要求生成仿射矩阵
(*this)(image, T, patch, patchSize, rng);//使用仿射矩阵做变换。
}
//生成仿射矩阵函数
voidPatchGenerator::generateRandomTransform(Point2f srcCenter, Point2f dstCenter,
Mat& transform, RNG& rng, bool inverse) const
{...}
//使用仿射矩阵做仿射变换
void PatchGenerator::operator ()(const Mat& image, const Mat& T,
Mat& patch, Size patchSize, RNG& rng) const
{
patch.create( patchSize, image.type() );
if( backgroundMin != backgroundMax )
{
rng.fill(patch, RNG::UNIFORM, Scalar::all(backgroundMin), Scalar::all(backgroundMax));
warpAffine(image, patch, T, patchSize, INTER_LINEAR, BORDER_TRANSPARENT);
//使用仿射矩阵T,对原图像做仿射变换,得到大小为patchSize的图像patch。
//INTER_LINEAR,表示缩放时使用双线性插值
//BORDER_TRANSPARENT表示仿射变换到原图像外的区域,不使用该函数。
//更多详情,参考OPENCV2.3.*文档资料
}
else
warpAffine(image, patch, T, patchSize, INTER_LINEAR, BORDER_CONSTANT, Scalar::all(backgroundMin));
int ksize = randomBlur ? (unsigned)rng % 9 - 5 : 0;
if( ksize > 0 )
{
ksize = ksize*2 + 1;
GaussianBlur(patch, patch, Size(ksize, ksize), 0, 0);
}
if( noiseRange > 0 )
{
AutoBuffer<uchar> _noiseBuf( patchSize.width*patchSize.height*image.elemSize() );
Mat noise(patchSize, image.type(), (uchar*)_noiseBuf);
int delta = image.depth() == CV_8U ? 128 : image.depth() == CV_16U ? 32768 : 0;
rng.fill(noise, RNG::NORMAL, Scalar::all(delta), Scalar::all(noiseRange));
if( backgroundMin != backgroundMax )
addWeighted(patch, 1, noise, 1, -delta, patch);
else
{
for( int i = 0; i < patchSize.height; i++ )
{
uchar* prow = patch.ptr<uchar>(i);
const uchar* nrow = noise.ptr<uchar>(i);
for( int j = 0; j < patchSize.width; j++ )
if( prow[j] != backgroundMin )
prow[j] = saturate_cast<uchar>(prow[j] + nrow[j] - delta);
}
}
}
}
TLD::init()中:
generator= PatchGenerator (0,0,noise_init,true,1-scale_init,1+scale_init,-angle_init*CV_PI/180,angle_init*CV_PI/180,-angle_init*CV_PI/180,angle_init*CV_PI/180);
作用:
初始化generator:
背景最小值:0
背景最大值:0
噪声范围:noise_init(0到)
是否模糊化:true
最小尺度:1-scale_init
最大尺度:1+scale_init
(即尺度变化范围为:1-scale_init 到 1+scale_init)
最小角度:-angle_init*CV_PI/180
最大角度:angle_init*CV_PI/180
(即旋转角度范围为-angle_init*CV_PI/180到
angle_init*CV_PI/180)
TLD::generatePositiveData()中:
generator(frame,pt,warped,bbhull.size(),rng);
对frame进行仿射变换,将仿射变换结果保存到warped。