mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-19 19:44:14 +08:00
KCF speedup (#1374)
* kcf use float data type rather than double. In our practice, float is good enough and could get better performance. With this patch, one of my benchmark could get about 20% performance gain. Signed-off-by: Zhigang Gong <zhigang.gong@intel.com> * Offload transpose matrix multiplication to ocl. The matrix multiplication in updateProjectMatrix is one of the hotspot. And because of the matrix shape is special, say the m is very short but the n is very large. The GEMM implementation in neither the clBLAS nor the in trunk implementation are very inefficient, I implement an standalone transpose matrix mulplication kernel here. It can get about 10% performance gain on Intel desktop platform or 20% performance gain on a braswell platform. And in the mean time, the CPU utilization will be lower. Signed-off-by: Zhigang Gong <zhigang.gong@intel.com> * Add verification code for kcf ocl transpose mm kernel. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com> * tracking: show FPS in traker sample * tracking: fix MSVC warnings in KCF * tracking: move OCL kernel initialization to constructor in KCF
This commit is contained in:

committed by
Vadim Pisarevsky

parent
0058eca130
commit
41995b76e8
@@ -1236,12 +1236,12 @@ public:
|
||||
*/
|
||||
void write(FileStorage& /*fs*/) const;
|
||||
|
||||
double detect_thresh; //!< detection confidence threshold
|
||||
double sigma; //!< gaussian kernel bandwidth
|
||||
double lambda; //!< regularization
|
||||
double interp_factor; //!< linear interpolation factor for adaptation
|
||||
double output_sigma_factor; //!< spatial bandwidth (proportional to target)
|
||||
double pca_learning_rate; //!< compression learning rate
|
||||
float detect_thresh; //!< detection confidence threshold
|
||||
float sigma; //!< gaussian kernel bandwidth
|
||||
float lambda; //!< regularization
|
||||
float interp_factor; //!< linear interpolation factor for adaptation
|
||||
float output_sigma_factor; //!< spatial bandwidth (proportional to target)
|
||||
float pca_learning_rate; //!< compression learning rate
|
||||
bool resize; //!< activate the resize feature to improve the processing speed
|
||||
bool split_coeff; //!< split the training coefficients into two matrices
|
||||
bool wrap_kernel; //!< wrap around the kernel values
|
||||
|
@@ -117,6 +117,7 @@ int main( int argc, char** argv ){
|
||||
|
||||
bool initialized = false;
|
||||
int frameCounter = 0;
|
||||
int64 timeTotal = 0;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
@@ -142,11 +143,14 @@ int main( int argc, char** argv ){
|
||||
}
|
||||
else if( initialized )
|
||||
{
|
||||
int64 frameTime = getTickCount();
|
||||
//updates the tracker
|
||||
if( tracker->update( frame, boundingBox ) )
|
||||
{
|
||||
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
|
||||
}
|
||||
frameTime = getTickCount() - frameTime;
|
||||
timeTotal += frameTime;
|
||||
}
|
||||
imshow( "Tracking API", image );
|
||||
frameCounter++;
|
||||
@@ -159,5 +163,8 @@ int main( int argc, char** argv ){
|
||||
paused = !paused;
|
||||
}
|
||||
|
||||
double s = frameCounter / (timeTotal / getTickFrequency());
|
||||
printf("FPS: %f\n", s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
77
modules/tracking/src/opencl/tmm.cl
Normal file
77
modules/tracking/src/opencl/tmm.cl
Normal file
@@ -0,0 +1,77 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// Copyright (C) 2016, Intel, Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#define LOCAL_SIZE_X 64
|
||||
#define BLOCK_SIZE_X 3
|
||||
|
||||
__kernel void tmm(__global float *A, int m, int n, float alpha, __global float *D)
|
||||
{
|
||||
int lidX = get_local_id(0);
|
||||
uint lsizeX = get_local_size(0);
|
||||
|
||||
uint matI = get_group_id(1);
|
||||
uint matJ = get_group_id(0);
|
||||
|
||||
if (matI < matJ)
|
||||
return;
|
||||
|
||||
__local float4 a[LOCAL_SIZE_X], b[LOCAL_SIZE_X];
|
||||
float4 result;
|
||||
__local uint cnt;
|
||||
result = 0;
|
||||
cnt = 0;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
do {
|
||||
// load block data to SLM.
|
||||
int global_block_base = (lidX + cnt * lsizeX) * BLOCK_SIZE_X;
|
||||
float4 pa[BLOCK_SIZE_X], pb[BLOCK_SIZE_X];
|
||||
|
||||
#pragma unroll
|
||||
for(uint j = 0; j < BLOCK_SIZE_X && (cnt * lsizeX + lidX) * BLOCK_SIZE_X < n / 4; j++) {
|
||||
pa[j] = *(__global float4*)&A[matI * n + (global_block_base + j) * 4];
|
||||
if (matI != matJ)
|
||||
pb[j] = *(__global float4*)&A[matJ * n + (global_block_base + j) * 4];
|
||||
else
|
||||
pb[j] = pa[j];
|
||||
}
|
||||
|
||||
// zero the data out-of-boundary.
|
||||
if (global_block_base + BLOCK_SIZE_X - 1 >= n/4) {
|
||||
#pragma unroll
|
||||
for(int i = 0; i < BLOCK_SIZE_X; i++) {
|
||||
if (global_block_base + i >= n/4)
|
||||
pb[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pb[0] *= pa[0];
|
||||
|
||||
for(int j = 1; j < BLOCK_SIZE_X; j++)
|
||||
pb[0] = fma(pb[j], pa[j], pb[0]);
|
||||
|
||||
b[lidX] = pb[0];
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
// perform reduce add
|
||||
for(int offset = LOCAL_SIZE_X / 2; offset > 0; offset >>= 1) {
|
||||
if (lidX < offset)
|
||||
b[lidX] += b[(lidX + offset)];
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
if (lidX == 0) {
|
||||
result += b[0];
|
||||
cnt++;
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
} while(cnt * BLOCK_SIZE_X * lsizeX < n / 4);
|
||||
if (lidX == 0) {
|
||||
float ret = (result.s0 + result.s1 + result.s2 + result.s3) * alpha;
|
||||
D[matI * m + matJ] = ret;
|
||||
if (matI != matJ)
|
||||
D[matJ * m + matI] = ret;
|
||||
}
|
||||
}
|
@@ -42,6 +42,7 @@
|
||||
#ifndef __OPENCV_PRECOMP_H__
|
||||
#define __OPENCV_PRECOMP_H__
|
||||
|
||||
#include "cvconfig.h"
|
||||
#include "opencv2/tracking.hpp"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#include "opencv2/core/ocl.hpp"
|
||||
@@ -50,7 +51,7 @@
|
||||
|
||||
namespace cv
|
||||
{
|
||||
extern const double ColorNames[][10];
|
||||
extern const float ColorNames[][10];
|
||||
|
||||
namespace tracking {
|
||||
|
||||
|
@@ -40,7 +40,9 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_tracking.hpp"
|
||||
#include <complex>
|
||||
#include <cmath>
|
||||
|
||||
/*---------------------------
|
||||
| TrackerKCFModel
|
||||
@@ -93,13 +95,13 @@ namespace cv{
|
||||
void inline ifft2(const Mat src, Mat & dest) const;
|
||||
void inline pixelWiseMult(const std::vector<Mat> src1, const std::vector<Mat> src2, std::vector<Mat> & dest, const int flags, const bool conjB=false) const;
|
||||
void inline sumChannels(std::vector<Mat> src, Mat & dest) const;
|
||||
void inline updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & proj_matrix,double pca_rate, int compressed_sz,
|
||||
std::vector<Mat> & layers_pca,std::vector<Scalar> & average, Mat pca_data, Mat new_cov, Mat w, Mat u, Mat v) const;
|
||||
void inline updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & proj_matrix,float pca_rate, int compressed_sz,
|
||||
std::vector<Mat> & layers_pca,std::vector<Scalar> & average, Mat pca_data, Mat new_cov, Mat w, Mat u, Mat v);
|
||||
void inline compress(const Mat proj_matrix, const Mat src, Mat & dest, Mat & data, Mat & compressed) const;
|
||||
bool getSubWindow(const Mat img, const Rect roi, Mat& feat, Mat& patch, TrackerKCF::MODE desc = GRAY) const;
|
||||
bool getSubWindow(const Mat img, const Rect roi, Mat& feat, void (*f)(const Mat, const Rect, Mat& )) const;
|
||||
void extractCN(Mat patch_data, Mat & cnFeatures) const;
|
||||
void denseGaussKernel(const double sigma, const Mat , const Mat y_data, Mat & k_data,
|
||||
void denseGaussKernel(const float sigma, const Mat , const Mat y_data, Mat & k_data,
|
||||
std::vector<Mat> & layers_data,std::vector<Mat> & xf_data,std::vector<Mat> & yf_data, std::vector<Mat> xyf_v, Mat xy, Mat xyf ) const;
|
||||
void calcResponse(const Mat alphaf_data, const Mat kf_data, Mat & response_data, Mat & spec_data) const;
|
||||
void calcResponse(const Mat alphaf_data, const Mat alphaf_den_data, const Mat kf_data, Mat & response_data, Mat & spec_data, Mat & spec2_data) const;
|
||||
@@ -107,9 +109,12 @@ namespace cv{
|
||||
void shiftRows(Mat& mat) const;
|
||||
void shiftRows(Mat& mat, int n) const;
|
||||
void shiftCols(Mat& mat, int n) const;
|
||||
#ifdef HAVE_OPENCL
|
||||
bool inline oclTransposeMM(const Mat src, float alpha, UMat &dst);
|
||||
#endif
|
||||
|
||||
private:
|
||||
double output_sigma;
|
||||
float output_sigma;
|
||||
Rect2d roi;
|
||||
Mat hann; //hann window filter
|
||||
Mat hann_cn; //10 dimensional hann-window filter for CN features,
|
||||
@@ -154,6 +159,10 @@ namespace cv{
|
||||
|
||||
bool resizeImage; // resize the image whenever needed and the patch size is large
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
ocl::Kernel transpose_mm_ker; // OCL kernel to compute transpose matrix multiply matrix.
|
||||
#endif
|
||||
|
||||
int frame;
|
||||
};
|
||||
|
||||
@@ -174,6 +183,16 @@ namespace cv{
|
||||
use_custom_extractor_pca = false;
|
||||
use_custom_extractor_npca = false;
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
// For update proj matrix's multiplication
|
||||
if(ocl::useOpenCL())
|
||||
{
|
||||
cv::String err;
|
||||
ocl::ProgramSource tmmSrc = ocl::tracking::tmm_oclsrc;
|
||||
ocl::Program tmmProg(tmmSrc, String(), err);
|
||||
transpose_mm_ker.create("tmm", tmmProg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TrackerKCFImpl::read( const cv::FileNode& fn ){
|
||||
@@ -196,8 +215,8 @@ namespace cv{
|
||||
roi = boundingBox;
|
||||
|
||||
//calclulate output sigma
|
||||
output_sigma=sqrt(roi.width*roi.height)*params.output_sigma_factor;
|
||||
output_sigma=-0.5/(output_sigma*output_sigma);
|
||||
output_sigma=std::sqrt(static_cast<float>(roi.width*roi.height))*params.output_sigma_factor;
|
||||
output_sigma=-0.5f/(output_sigma*output_sigma);
|
||||
|
||||
//resize the ROI whenever needed
|
||||
if(params.resize && roi.width*roi.height>params.max_patch_size){
|
||||
@@ -215,21 +234,22 @@ namespace cv{
|
||||
roi.height*=2;
|
||||
|
||||
// initialize the hann window filter
|
||||
createHanningWindow(hann, roi.size(), CV_64F);
|
||||
createHanningWindow(hann, roi.size(), CV_32F);
|
||||
|
||||
// hann window filter for CN feature
|
||||
Mat _layer[] = {hann, hann, hann, hann, hann, hann, hann, hann, hann, hann};
|
||||
merge(_layer, 10, hann_cn);
|
||||
|
||||
// create gaussian response
|
||||
y=Mat::zeros((int)roi.height,(int)roi.width,CV_64F);
|
||||
for(unsigned i=0;i<(unsigned)roi.height;i++){
|
||||
for(unsigned j=0;j<(unsigned)roi.width;j++){
|
||||
y.at<double>(i,j)=(i-roi.height/2+1)*(i-roi.height/2+1)+(j-roi.width/2+1)*(j-roi.width/2+1);
|
||||
y=Mat::zeros((int)roi.height,(int)roi.width,CV_32F);
|
||||
for(int i=0;i<roi.height;i++){
|
||||
for(int j=0;j<roi.width;j++){
|
||||
y.at<float>(i,j) =
|
||||
static_cast<float>((i-roi.height/2+1)*(i-roi.height/2+1)+(j-roi.width/2+1)*(j-roi.width/2+1));
|
||||
}
|
||||
}
|
||||
|
||||
y*=(double)output_sigma;
|
||||
y*=(float)output_sigma;
|
||||
cv::exp(y,y);
|
||||
|
||||
// perform fourier transfor to the gaussian response
|
||||
@@ -331,7 +351,7 @@ namespace cv{
|
||||
|
||||
// compute the fourier transform of the kernel
|
||||
fft2(k,kf);
|
||||
if(frame==1)spec2=Mat_<Vec2d >(kf.rows, kf.cols);
|
||||
if(frame==1)spec2=Mat_<Vec2f >(kf.rows, kf.cols);
|
||||
|
||||
// calculate filter response
|
||||
if(params.split_coeff)
|
||||
@@ -411,7 +431,7 @@ namespace cv{
|
||||
vxf.resize(x.channels());
|
||||
vyf.resize(x.channels());
|
||||
vxyf.resize(vyf.size());
|
||||
new_alphaf=Mat_<Vec2d >(yf.rows, yf.cols);
|
||||
new_alphaf=Mat_<Vec2f >(yf.rows, yf.cols);
|
||||
}
|
||||
|
||||
// Kernel Regularized Least-Squares, calculate alphas
|
||||
@@ -421,19 +441,19 @@ namespace cv{
|
||||
fft2(k,kf);
|
||||
kf_lambda=kf+params.lambda;
|
||||
|
||||
double den;
|
||||
float den;
|
||||
if(params.split_coeff){
|
||||
mulSpectrums(yf,kf,new_alphaf,0);
|
||||
mulSpectrums(kf,kf_lambda,new_alphaf_den,0);
|
||||
}else{
|
||||
for(int i=0;i<yf.rows;i++){
|
||||
for(int j=0;j<yf.cols;j++){
|
||||
den = 1.0/(kf_lambda.at<Vec2d>(i,j)[0]*kf_lambda.at<Vec2d>(i,j)[0]+kf_lambda.at<Vec2d>(i,j)[1]*kf_lambda.at<Vec2d>(i,j)[1]);
|
||||
den = 1.0f/(kf_lambda.at<Vec2f>(i,j)[0]*kf_lambda.at<Vec2f>(i,j)[0]+kf_lambda.at<Vec2f>(i,j)[1]*kf_lambda.at<Vec2f>(i,j)[1]);
|
||||
|
||||
new_alphaf.at<Vec2d>(i,j)[0]=
|
||||
(yf.at<Vec2d>(i,j)[0]*kf_lambda.at<Vec2d>(i,j)[0]+yf.at<Vec2d>(i,j)[1]*kf_lambda.at<Vec2d>(i,j)[1])*den;
|
||||
new_alphaf.at<Vec2d>(i,j)[1]=
|
||||
(yf.at<Vec2d>(i,j)[1]*kf_lambda.at<Vec2d>(i,j)[0]-yf.at<Vec2d>(i,j)[0]*kf_lambda.at<Vec2d>(i,j)[1])*den;
|
||||
new_alphaf.at<Vec2f>(i,j)[0]=
|
||||
(yf.at<Vec2f>(i,j)[0]*kf_lambda.at<Vec2f>(i,j)[0]+yf.at<Vec2f>(i,j)[1]*kf_lambda.at<Vec2f>(i,j)[1])*den;
|
||||
new_alphaf.at<Vec2f>(i,j)[1]=
|
||||
(yf.at<Vec2f>(i,j)[1]*kf_lambda.at<Vec2f>(i,j)[0]-yf.at<Vec2f>(i,j)[0]*kf_lambda.at<Vec2f>(i,j)[1])*den;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,24 +487,25 @@ namespace cv{
|
||||
|
||||
int rows = dst.rows, cols = dst.cols;
|
||||
|
||||
AutoBuffer<double> _wc(cols);
|
||||
double * const wc = (double *)_wc;
|
||||
AutoBuffer<float> _wc(cols);
|
||||
float * const wc = (float *)_wc;
|
||||
|
||||
double coeff0 = 2.0 * CV_PI / (double)(cols - 1), coeff1 = 2.0f * CV_PI / (double)(rows - 1);
|
||||
const float coeff0 = 2.0f * (float)CV_PI / (cols - 1);
|
||||
const float coeff1 = 2.0f * (float)CV_PI / (rows - 1);
|
||||
for(int j = 0; j < cols; j++)
|
||||
wc[j] = 0.5 * (1.0 - cos(coeff0 * j));
|
||||
wc[j] = 0.5f * (1.0f - cos(coeff0 * j));
|
||||
|
||||
if(dst.depth() == CV_32F){
|
||||
for(int i = 0; i < rows; i++){
|
||||
float* dstData = dst.ptr<float>(i);
|
||||
double wr = 0.5 * (1.0 - cos(coeff1 * i));
|
||||
float wr = 0.5f * (1.0f - cos(coeff1 * i));
|
||||
for(int j = 0; j < cols; j++)
|
||||
dstData[j] = (float)(wr * wc[j]);
|
||||
}
|
||||
}else{
|
||||
for(int i = 0; i < rows; i++){
|
||||
double* dstData = dst.ptr<double>(i);
|
||||
double wr = 0.5 * (1.0 - cos(coeff1 * i));
|
||||
double wr = 0.5f * (1.0f - cos(coeff1 * i));
|
||||
for(int j = 0; j < cols; j++)
|
||||
dstData[j] = wr * wc[j];
|
||||
}
|
||||
@@ -535,11 +556,37 @@ namespace cv{
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
bool inline TrackerKCFImpl::oclTransposeMM(const Mat src, float alpha, UMat &dst){
|
||||
// Current kernel only support matrix's rows is multiple of 4.
|
||||
// And if one line is less than 512KB, CPU will likely be faster.
|
||||
if (transpose_mm_ker.empty() ||
|
||||
src.rows % 4 != 0 ||
|
||||
(src.rows * 10) < (1024 * 1024 / 4))
|
||||
return false;
|
||||
|
||||
Size s(src.rows, src.cols);
|
||||
const Mat tmp = src.t();
|
||||
const UMat uSrc = tmp.getUMat(ACCESS_READ);
|
||||
transpose_mm_ker.args(
|
||||
ocl::KernelArg::PtrReadOnly(uSrc),
|
||||
(int)uSrc.rows,
|
||||
(int)uSrc.cols,
|
||||
alpha,
|
||||
ocl::KernelArg::PtrWriteOnly(dst));
|
||||
size_t globSize[2] = {static_cast<size_t>(src.cols * 64), static_cast<size_t>(src.cols)};
|
||||
size_t localSize[2] = {64, 1};
|
||||
if (!transpose_mm_ker.run(2, globSize, localSize, true))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* obtains the projection matrix using PCA
|
||||
*/
|
||||
void inline TrackerKCFImpl::updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & proj_matrix, double pca_rate, int compressed_sz,
|
||||
std::vector<Mat> & layers_pca,std::vector<Scalar> & average, Mat pca_data, Mat new_cov, Mat w, Mat u, Mat vt) const {
|
||||
void inline TrackerKCFImpl::updateProjectionMatrix(const Mat src, Mat & old_cov,Mat & proj_matrix, float pca_rate, int compressed_sz,
|
||||
std::vector<Mat> & layers_pca,std::vector<Scalar> & average, Mat pca_data, Mat new_cov, Mat w, Mat u, Mat vt) {
|
||||
CV_Assert(compressed_sz<=src.channels());
|
||||
|
||||
split(src,layers_pca);
|
||||
@@ -553,17 +600,40 @@ namespace cv{
|
||||
merge(layers_pca,pca_data);
|
||||
pca_data=pca_data.reshape(1,src.rows*src.cols);
|
||||
|
||||
new_cov=1.0/(double)(src.rows*src.cols-1)*(pca_data.t()*pca_data);
|
||||
#ifdef HAVE_OPENCL
|
||||
bool oclSucceed = false;
|
||||
Size s(pca_data.cols, pca_data.cols);
|
||||
UMat result(s, pca_data.type());
|
||||
if (oclTransposeMM(pca_data, 1.0/(float)(src.rows*src.cols-1), result)) {
|
||||
if(old_cov.rows==0) old_cov=result.getMat(ACCESS_READ).clone();
|
||||
SVD::compute((1.0-pca_rate)*old_cov + pca_rate * result.getMat(ACCESS_READ), w, u, vt);
|
||||
oclSucceed = true;
|
||||
}
|
||||
#define TMM_VERIFICATION 0
|
||||
|
||||
if (oclSucceed == false || TMM_VERIFICATION) {
|
||||
new_cov=1.0f/(float)(src.rows*src.cols-1)*(pca_data.t()*pca_data);
|
||||
#if TMM_VERIFICATION
|
||||
for(int i = 0; i < new_cov.rows; i++)
|
||||
for(int j = 0; j < new_cov.cols; j++)
|
||||
if (abs(new_cov.at<float>(i, j) - result.getMat(ACCESS_RW).at<float>(i , j)) > abs(new_cov.at<float>(i, j)) * 1e-3)
|
||||
printf("error @ i %d j %d got %G expected %G \n", i, j, result.getMat(ACCESS_RW).at<float>(i , j), new_cov.at<float>(i, j));
|
||||
#endif
|
||||
if(old_cov.rows==0)old_cov=new_cov.clone();
|
||||
SVD::compute((1.0f - pca_rate) * old_cov + pca_rate * new_cov, w, u, vt);
|
||||
}
|
||||
#else
|
||||
new_cov=1.0/(float)(src.rows*src.cols-1)*(pca_data.t()*pca_data);
|
||||
if(old_cov.rows==0)old_cov=new_cov.clone();
|
||||
|
||||
// calc PCA
|
||||
SVD::compute((1.0-pca_rate)*old_cov+pca_rate*new_cov, w, u, vt);
|
||||
|
||||
#endif
|
||||
// extract the projection matrix
|
||||
proj_matrix=u(Rect(0,0,compressed_sz,src.channels())).clone();
|
||||
Mat proj_vars=Mat::eye(compressed_sz,compressed_sz,proj_matrix.type());
|
||||
for(int i=0;i<compressed_sz;i++){
|
||||
proj_vars.at<double>(i,i)=w.at<double>(i);
|
||||
proj_vars.at<float>(i,i)=w.at<float>(i);
|
||||
}
|
||||
|
||||
// update the covariance matrix
|
||||
@@ -622,8 +692,9 @@ namespace cv{
|
||||
cvtColor(patch,feat, CV_BGR2GRAY);
|
||||
else
|
||||
feat=patch;
|
||||
feat.convertTo(feat,CV_64F);
|
||||
feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
|
||||
//feat.convertTo(feat,CV_32F);
|
||||
feat.convertTo(feat,CV_32F, 1.0/255.0, -0.5);
|
||||
//feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
|
||||
feat=feat.mul(hann); // hann window filter
|
||||
break;
|
||||
}
|
||||
@@ -670,8 +741,8 @@ namespace cv{
|
||||
Vec3b & pixel = patch_data.at<Vec3b>(0,0);
|
||||
unsigned index;
|
||||
|
||||
if(cnFeatures.type() != CV_64FC(10))
|
||||
cnFeatures = Mat::zeros(patch_data.rows,patch_data.cols,CV_64FC(10));
|
||||
if(cnFeatures.type() != CV_32FC(10))
|
||||
cnFeatures = Mat::zeros(patch_data.rows,patch_data.cols,CV_32FC(10));
|
||||
|
||||
for(int i=0;i<patch_data.rows;i++){
|
||||
for(int j=0;j<patch_data.cols;j++){
|
||||
@@ -680,7 +751,7 @@ namespace cv{
|
||||
|
||||
//copy the values
|
||||
for(int _k=0;_k<10;_k++){
|
||||
cnFeatures.at<Vec<double,10> >(i,j)[_k]=ColorNames[index][_k];
|
||||
cnFeatures.at<Vec<float,10> >(i,j)[_k]=ColorNames[index][_k];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -690,7 +761,7 @@ namespace cv{
|
||||
/*
|
||||
* dense gauss kernel function
|
||||
*/
|
||||
void TrackerKCFImpl::denseGaussKernel(const double sigma, const Mat x_data, const Mat y_data, Mat & k_data,
|
||||
void TrackerKCFImpl::denseGaussKernel(const float sigma, const Mat x_data, const Mat y_data, Mat & k_data,
|
||||
std::vector<Mat> & layers_data,std::vector<Mat> & xf_data,std::vector<Mat> & yf_data, std::vector<Mat> xyf_v, Mat xy, Mat xyf ) const {
|
||||
double normX, normY;
|
||||
|
||||
@@ -718,11 +789,11 @@ namespace cv{
|
||||
//threshold(xy,xy,0.0,0.0,THRESH_TOZERO);//max(0, (xx + yy - 2 * xy) / numel(x))
|
||||
for(int i=0;i<xy.rows;i++){
|
||||
for(int j=0;j<xy.cols;j++){
|
||||
if(xy.at<double>(i,j)<0.0)xy.at<double>(i,j)=0.0;
|
||||
if(xy.at<float>(i,j)<0.0)xy.at<float>(i,j)=0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double sig=-1.0/(sigma*sigma);
|
||||
float sig=-1.0f/(sigma*sigma);
|
||||
xy=sig*xy;
|
||||
exp(xy,k_data);
|
||||
|
||||
@@ -796,14 +867,14 @@ namespace cv{
|
||||
mulSpectrums(alphaf_data,kf_data,spec_data,0,false);
|
||||
|
||||
//z=(a+bi)/(c+di)=[(ac+bd)+i(bc-ad)]/(c^2+d^2)
|
||||
double den;
|
||||
float den;
|
||||
for(int i=0;i<kf_data.rows;i++){
|
||||
for(int j=0;j<kf_data.cols;j++){
|
||||
den=1.0/(_alphaf_den.at<Vec2d>(i,j)[0]*_alphaf_den.at<Vec2d>(i,j)[0]+_alphaf_den.at<Vec2d>(i,j)[1]*_alphaf_den.at<Vec2d>(i,j)[1]);
|
||||
spec2_data.at<Vec2d>(i,j)[0]=
|
||||
(spec_data.at<Vec2d>(i,j)[0]*_alphaf_den.at<Vec2d>(i,j)[0]+spec_data.at<Vec2d>(i,j)[1]*_alphaf_den.at<Vec2d>(i,j)[1])*den;
|
||||
spec2_data.at<Vec2d>(i,j)[1]=
|
||||
(spec_data.at<Vec2d>(i,j)[1]*_alphaf_den.at<Vec2d>(i,j)[0]-spec_data.at<Vec2d>(i,j)[0]*_alphaf_den.at<Vec2d>(i,j)[1])*den;
|
||||
den=1.0f/(_alphaf_den.at<Vec2f>(i,j)[0]*_alphaf_den.at<Vec2f>(i,j)[0]+_alphaf_den.at<Vec2f>(i,j)[1]*_alphaf_den.at<Vec2f>(i,j)[1]);
|
||||
spec2_data.at<Vec2f>(i,j)[0]=
|
||||
(spec_data.at<Vec2f>(i,j)[0]*_alphaf_den.at<Vec2f>(i,j)[0]+spec_data.at<Vec2f>(i,j)[1]*_alphaf_den.at<Vec2f>(i,j)[1])*den;
|
||||
spec2_data.at<Vec2f>(i,j)[1]=
|
||||
(spec_data.at<Vec2f>(i,j)[1]*_alphaf_den.at<Vec2f>(i,j)[0]-spec_data.at<Vec2f>(i,j)[0]*_alphaf_den.at<Vec2f>(i,j)[1])*den;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,11 +896,11 @@ namespace cv{
|
||||
* Parameters
|
||||
*/
|
||||
TrackerKCF::Params::Params(){
|
||||
detect_thresh = 0.5;
|
||||
sigma=0.2;
|
||||
lambda=0.0001;
|
||||
interp_factor=0.075;
|
||||
output_sigma_factor=1.0/16.0;
|
||||
detect_thresh = 0.5f;
|
||||
sigma=0.2f;
|
||||
lambda=0.0001f;
|
||||
interp_factor=0.075f;
|
||||
output_sigma_factor=1.0f / 16.0f;
|
||||
resize=true;
|
||||
max_patch_size=80*80;
|
||||
split_coeff=true;
|
||||
@@ -840,7 +911,7 @@ namespace cv{
|
||||
//feature compression
|
||||
compress_feature=true;
|
||||
compressed_size=2;
|
||||
pca_learning_rate=0.15;
|
||||
pca_learning_rate=0.15f;
|
||||
}
|
||||
|
||||
void TrackerKCF::Params::read( const cv::FileNode& fn ){
|
||||
|
@@ -63,10 +63,10 @@ TEST(KCF_Parameters, IO)
|
||||
{
|
||||
TrackerKCF::Params parameters;
|
||||
|
||||
parameters.sigma = 0.3;
|
||||
parameters.lambda = 0.02;
|
||||
parameters.interp_factor = 0.08;
|
||||
parameters.output_sigma_factor = 1.0/ 32.0;
|
||||
parameters.sigma = 0.3f;
|
||||
parameters.lambda = 0.02f;
|
||||
parameters.interp_factor = 0.08f;
|
||||
parameters.output_sigma_factor = 1.0f/ 32.0f;
|
||||
parameters.resize=false;
|
||||
parameters.max_patch_size=90*90;
|
||||
parameters.split_coeff=false;
|
||||
@@ -75,7 +75,7 @@ TEST(KCF_Parameters, IO)
|
||||
parameters.desc_pca = TrackerKCF::GRAY;
|
||||
parameters.compress_feature=false;
|
||||
parameters.compressed_size=3;
|
||||
parameters.pca_learning_rate=0.2;
|
||||
parameters.pca_learning_rate=0.2f;
|
||||
|
||||
FileStorage fsWriter("parameters.xml", FileStorage::WRITE + FileStorage::MEMORY);
|
||||
parameters.write(fsWriter);
|
||||
|
Reference in New Issue
Block a user