#include "MatchTemp.h"
#include <ctime>
struct Min_Val
{
int index;
float val;
};
Min_Val index_min_val(vector<float> fv)
{
int index = -1;
float minVal = FLT_MAX;
for (size_t i=0;i<fv.size();++i)
{
if (minVal>fv[i])
{
minVal = fv[i];
index = i;
}
}
Min_Val mv;
mv.index = index;
mv.val = minVal;
return mv;
}
inline Mat repmat(const Mat inM,int rows)
{
Mat outM = Mat(0,inM.cols,inM.type());
for ( int i=0;i<rows;++i)
{
outM.push_back(inM);
}
return outM;
}
CMatchTemp::CMatchTemp(void)
{
m_epsilon = 0.15f;
m_delta = 0.25f;
m_minScale = 0.5f;
m_maxScale = 2.0f;
}
CMatchTemp::~CMatchTemp(void)
{
}
//使行列为奇数,数值范围[0,1]
Mat CMatchTemp::makeOdd(const Mat& img)
{
int rows = img.rows;
int cols = img.cols;
if (rows%2==0)
{
rows -= 1;
}
if (cols%2==0)
{
cols -= 1;
}
Mat roi = img(Rect(0,0,cols,rows));
Mat out ;
roi.convertTo(out,CV_32FC1,1.0f/255);
return out;
}
//生成约束边界和步长
void CMatchTemp::GenerateGrid(float sourceW,float sourceH,float _delta,
float minTx,float maxTx, float minTy, float maxTy,
float minR,float maxR,float minS,float maxS)
{
m_bounds.tx[0] = minTx; m_bounds.tx[1] = maxTx ;
m_bounds.ty[0] = minTy; m_bounds.ty[1] = maxTy;
m_bounds.r[0] = minR; m_bounds.r[1] = maxR;
m_bounds.s[0] = minS; m_bounds.s[1] = maxS; // [1/c,c]
m_steps.tx = _delta*sourceW/sqrt(2.0f);
m_steps.ty = _delta*sourceH/sqrt(2.0f);
m_steps.r = _delta*sqrt(2.0f);
m_steps.s = _delta/sqrt(2.0f);
}
Mat CMatchTemp::match(Mat img,Mat temp)
{
float blur_sigma = 2.0;
GaussianBlur(img,img,Size(0,0),blur_sigma,blur_sigma);
GaussianBlur(temp,temp,Size(0,0),blur_sigma,blur_sigma);
src_img = makeOdd(img);
temp_img = makeOdd(temp);
h1 = temp_img.rows;
w1 = temp_img.cols;
h2 = src_img.rows;
w2 = src_img.cols;
r1x = 0.5f*(w1-1);
r1y = 0.5f*(h1-1);
r2x = 0.5f*(w2-1);
r2y = 0.5f*(h2-1);
//搜索范围
float minTx = -(r2x-r1x*m_minScale);
float maxTx = r2x-r1x*m_minScale;
float minTy = -(r2y-r1y*m_minScale);
float maxTy = r2y-r1y*m_minScale;
float minR =(float) -CV_PI;
float maxR = (float) CV_PI;
//生成限制
GenerateGrid(h1,w1,m_delta,minTx,maxTx,minTy,maxTy,minR,maxR,m_minScale,m_maxScale);
//寻找最佳变换
bestTransMat = FindBestTransformation();
return bestTransMat;
}
Mat CMatchTemp::FindBestTransformation()
{
static Mat src_cpy = src_img.clone();
Mat bestTransMat;
RNG rng(time(NULL));
//生成 Theta(1/eps^2) 个随机样本点
long numPoints = cvRound(8/(m_epsilon*m_epsilon));
vector<float> xs(numPoints);
vector<float> ys(numPoints);
for (int i=0;i<numPoints;++i)
{
xs[i] = (float) rng.uniform(5,w1-5);
ys[i] = (float) rng.uniform(5,h1-5);
}
//生成网络
Mat configs;
int gridSize = CreateListOfConfigs(configs);
if ( gridSize > 71000000)
cout<<"more than 35 million configs!"<<endl;
Mat goodConfigsStats = Mat(0,6,CV_32FC1);
//主循环
float deltaFact = 1.511f;
int level = 0;
vector<float> bestDists;
float newDelta = m_delta;
while(1)
{
// 1.选出变换后的坐标落在图像区域中的变换坐标
Mat matrixConfigs_mex;
vector<bool> insiders;
GetAffineFromConfig(configs,matrixConfigs_mex,insiders);
cout<<"gridSize: "<<configs.rows<<" ";
GetInsideMat(configs,matrixConfigs_mex,insiders);
// 2.评估这些变换
double tic = getTickCount();
vector<float> distances = EvaluateConfigs_mex(matrixConfigs_mex, xs, ys);
cout<<"EvaluateConfigs_mex 耗时:"<<(getTickCount()-tic)/getTickFrequency()<<"s"<<endl;
Min_Val mini_ = index_min_val(distances);
int ind = mini_.index;
float bestDist = mini_.val;
Mat bestConfig = configs.row(ind);
CreateAffineTransformation(bestConfig,bestTransMat);
// cout<<"best tran:"<<bestTransMat<<endl;
bestDists.push_back(bestDist);
Mat temp = drawMatch(src_cpy,temp_img,bestTransMat,255 - level * 60);
imshow("re",temp);
waitKey(1000);
//if (exist('goodConfigs','var'))
// goodConfigsStats = size(goodConfigs,1);
//end
cout<<" level---"<<level<<",best dist:"<<bestDist<<endl;
//退出机制
if ( (bestDist < 0.009) || ((level > 0) && (bestDist < 0.019)) || (level >= 10)
/* || ((level > 3) && (bestDist > mean(bestDists(level-3:level-1))*0.97)) */
/*|| ((level > 8) && (goodConfigsStats(end) > 20 ) )*/ )
{
break;
}
// 3 . 更新变换网络
//3.1 挑选
Mat goodConfigs ;
bool ishighPer = GetGoodConfigsByDistance(configs,bestDist,newDelta,distances,goodConfigs);
//3.2 扩展
if (ishighPer && level==0)
{
float fact = 0.99f;
//fprintf('##### RESTARTING!!! changing from delta: %.3f, to delta: %.3f\n', newDelta, newDelta*fact);
newDelta = newDelta*fact;
//level = 0;
m_steps.tx *= fact;
m_steps.ty *= fact;
m_steps.r *= fact;
m_steps.s *=fact;
CreateListOfConfigs(configs);
}
else
{
//float prevDelta = newDelta;
newDelta = newDelta/deltaFact;
Mat expandedConfigs = ExpandConfigsRandom(goodConfigs,m_steps,level,80,deltaFact);
configs.release();
configs = Mat(0,6,CV_32FC1);
configs.push_back(goodConfigs);
configs.push_back(expandedConfigs);
}
// 4 . 更新
level++;
for (int i=0;i<numPoints;++i)
{
xs[i] = (float) rng.uniform(5,w1-5);
ys[i] = (float) rng.uniform(5,h1-5);
}
}
// 返回最佳变换
return bestTransMat;
}
long CMatchTemp::CreateListOfConfigs(Mat& configs)
{
configs.release();
vector<float> tx_steps = get_vec_by_setp(m_bounds.tx[0] , m_steps.tx , m_bounds.tx[1]);
vector<float> ty_steps = get_vec_by_setp(m_bounds.ty[0] , m_steps.ty , m_bounds.ty[1]);
vector<float> r_steps = get_vec_by_setp(m_bounds.r[0] , m_steps.r , m_bounds.r[1]);
vector<float> s_steps = get_vec_by_setp(m_bounds.s[0] , m_steps.s , m_bounds.s[1]);
if (abs(m_steps.s) ==0)
{
s_steps.clear();
s_steps.push_back(m_bounds.s[0]);
}
if (m_bounds.tx[1]-tx_steps.back() > 0.5 * m_steps.tx)
{
tx_steps .push_back( tx_steps.back() + m_steps.tx ) ;
}
if (m_bounds.ty[1]-ty_steps.back() > 0.5 * m_steps.ty)
{
ty_steps .push_back ( ty_steps.back() + m_steps.ty);
}
if (m_bounds.r[1]-r_steps.back() > m_steps.r) // 这个具有周期性
{
r_steps .push_back ( r_steps.back() + m_steps.r);
}
if (m_bounds.s[1]-s_steps.back() > 0.5 * m_steps.s)
{
s_steps.push_back( s_steps.back() + m_steps.s);
}
size_t ntx_steps = tx_steps.size();
size_t nty_steps = (ty_steps).size();
size_t ns_steps = (s_steps).size();
size_t nr_steps = (r_steps).size();
size_t NR2_steps = 0;
for (size_t i=0;i<r_steps.size();++i)
{
if (r_steps[i] < -CV_PI/2 + m_steps.r/2 )
{
NR2_steps++;
}
}
long gridSize = ntx_steps*nty_steps*(ns_steps*ns_steps)*(nr_steps*NR2_steps);
configs = Mat(0,6,CV_32FC1);
int gridInd = 0;
float tx,ty,r2,sx,sy,r1;
for (size_t tx_ind = 0 ;tx_ind< ntx_steps;tx_ind++)
{
tx = tx_steps[tx_ind];
for(size_t ty_ind = 0 ;ty_ind< nty_steps ;ty_ind++)
{
ty = ty_steps[ty_ind];
for(size_t r1_ind = 0;r1_ind< nr_steps;++r1_ind)
{
r1 = r_steps[r1_ind];
for(size_t r2_ind = 0; r2_ind<NR2_steps ;++r2_ind)
{
r2 = r_steps[r2_ind];
for(size_t sx_ind = 0;sx_ind< ns_steps;++sx_ind)
{
sx = s_steps[sx_ind];
for(size_t sy_ind = 0; sy_ind<ns_steps;++sy_ind)
{
sy = s_steps[sy_ind];
gridInd = gridInd + 1;
float f6[] = {tx,ty,r2,sx,sy,r1};
Mat temp = Mat(1,6,CV_32FC1,f6);
configs.push_back(temp);
}
}
}
}
}
}
return gridSize;
}
inline vector<float> CMatchTemp::get_vec_by_setp(float start,float setp,float end)
{
vector<float> out;
while (start<=end)
{
out.push_back(start);
start += setp;
}
return out;
}
void CMatchTemp::GetAffineFromConfig(const Mat& conf,Mat& out1
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
fastMatch.zip (3个子文件)
MatchTemp.cpp 18KB
MatchTemp.h 2KB
main.cpp 948B
共 3 条
- 1
资源评论
这个不开车的老司机
- 粉丝: 46
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功