Commit 21d9c47b authored by shimat's avatar shimat Committed by Vadim Pisarevsky

Optimize decolor in photo (#10997)

* optimized cv::decolor by removing vector.push_back

* restored CV_INSTRUMENT_REGION() and original indent

* fix build warnings in contrast_preserve.hpp

* undo refactoring contrast_preserve.cpp/hpp
parent 514f4193
...@@ -82,7 +82,7 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost) ...@@ -82,7 +82,7 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
vector <double> Cg; vector <double> Cg;
vector < vector <double> > polyGrad; vector < vector <double> > polyGrad;
vector < vector < int > > comb; vector <Vec3i> comb;
vector <double> alf; vector <double> alf;
...@@ -103,11 +103,11 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost) ...@@ -103,11 +103,11 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
iterCount +=1; iterCount +=1;
pre_E = E; pre_E = E;
vector <double> G_pos; vector <double> G_pos(alf.size());
vector <double> G_neg; vector <double> G_neg(alf.size());
vector <double> temp; vector <double> temp(polyGrad[0].size());
vector <double> temp1; vector <double> temp1(polyGrad[0].size());
double val = 0.0; double val = 0.0;
for(unsigned int i=0;i< polyGrad[0].size();i++) for(unsigned int i=0;i< polyGrad[0].size();i++)
...@@ -115,8 +115,8 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost) ...@@ -115,8 +115,8 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
val = 0.0; val = 0.0;
for(unsigned int j =0;j<polyGrad.size();j++) for(unsigned int j =0;j<polyGrad.size();j++)
val = val + (polyGrad[j][i] * wei[j]); val = val + (polyGrad[j][i] * wei[j]);
temp.push_back(val - Cg[i]); temp[i] = val - Cg[i];
temp1.push_back(val + Cg[i]); temp1[i] = val + Cg[i];
} }
double pos = 0.0; double pos = 0.0;
...@@ -125,31 +125,31 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost) ...@@ -125,31 +125,31 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
{ {
pos = ((1 + alf[i])/2) * exp((-1.0 * 0.5 * pow(temp[i],2))/pow(obj.sigma,2)); pos = ((1 + alf[i])/2) * exp((-1.0 * 0.5 * pow(temp[i],2))/pow(obj.sigma,2));
neg = ((1 - alf[i])/2) * exp((-1.0 * 0.5 * pow(temp1[i],2))/pow(obj.sigma,2)); neg = ((1 - alf[i])/2) * exp((-1.0 * 0.5 * pow(temp1[i],2))/pow(obj.sigma,2));
G_pos.push_back(pos); G_pos[i] = pos;
G_neg.push_back(neg); G_neg[i] = neg;
} }
vector <double> EXPsum; vector <double> EXPsum(G_pos.size());
vector <double> EXPterm; vector <double> EXPterm(G_pos.size());
for(unsigned int i = 0;i<G_pos.size();i++) for(unsigned int i = 0;i<G_pos.size();i++)
EXPsum.push_back(G_pos[i]+G_neg[i]); EXPsum[i] = G_pos[i]+G_neg[i];
vector <double> temp2; vector <double> temp2(EXPsum.size());
for(unsigned int i=0;i<EXPsum.size();i++) for(unsigned int i=0;i<EXPsum.size();i++)
{ {
if(EXPsum[i] == 0) if(EXPsum[i] == 0)
temp2.push_back(1.0); temp2[i] = 1.0;
else else
temp2.push_back(0.0); temp2[i] = 0.0;
} }
for(unsigned int i =0; i < G_pos.size();i++) for(unsigned int i =0; i < G_pos.size();i++)
EXPterm.push_back((G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i])); EXPterm[i] = ((G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i]));
double val1 = 0.0; double val1 = 0.0;
vector <double> wei1; vector <double> wei1(polyGrad.size());
for(unsigned int i=0;i< polyGrad.size();i++) for(unsigned int i=0;i< polyGrad.size();i++)
{ {
...@@ -158,7 +158,7 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost) ...@@ -158,7 +158,7 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _color_boost)
{ {
val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]); val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]);
} }
wei1.push_back(val1); wei1[i] = val1;
} }
for(unsigned int i =0;i<wei.size();i++) for(unsigned int i =0;i<wei.size();i++)
......
...@@ -58,19 +58,19 @@ class Decolor ...@@ -58,19 +58,19 @@ class Decolor
public: public:
float sigma; float sigma;
void init(); void init();
vector<double> product(vector < vector<int> > &comb, vector <double> &initRGB); vector<double> product(vector <Vec3i> &comb, const double initRGB[3]);
double energyCalcu(vector <double> &Cg, vector < vector <double> > &polyGrad, vector <double> &wei); double energyCalcu(vector <double> &Cg, vector < vector <double> > &polyGrad, vector <double> &wei);
void singleChannelGradx(const Mat &img, Mat& dest); void singleChannelGradx(const Mat &img, Mat& dest);
void singleChannelGrady(const Mat &img, Mat& dest); void singleChannelGrady(const Mat &img, Mat& dest);
void gradvector(const Mat &img, vector <double> &grad); void gradvector(const Mat &img, vector <double> &grad);
void colorGrad(Mat img, vector <double> &Cg); void colorGrad(Mat img, vector <double> &Cg);
void add_vector(vector < vector <int> > &comb, int &idx, int r,int g,int b); void add_vector(vector <Vec3i> &comb, int &idx, int r,int g,int b);
void add_to_vector_poly(vector < vector <double> > &polyGrad, vector <double> &curGrad, int &idx1); void add_to_vector_poly(vector < vector <double> > &polyGrad, vector <double> &curGrad, int &idx1);
void weak_order(Mat img, vector <double> &alf); void weak_order(Mat img, vector <double> &alf);
void grad_system(Mat img, vector < vector < double > > &polyGrad, void grad_system(Mat img, vector < vector < double > > &polyGrad,
vector < double > &Cg, vector < vector <int> >& comb); vector < double > &Cg, vector <Vec3i>& comb);
void wei_update_matrix(vector < vector <double> > &poly, vector <double> &Cg, Mat &X); void wei_update_matrix(vector < vector <double> > &poly, vector <double> &Cg, Mat &X);
void wei_inti(vector < vector <int> > &comb, vector <double> &wei); void wei_inti(vector <Vec3i> &comb, vector <double> &wei);
void grayImContruct(vector <double> &wei, Mat img, Mat &Gray); void grayImContruct(vector <double> &wei, Mat img, Mat &Gray);
}; };
...@@ -83,25 +83,26 @@ int round_num(double a) ...@@ -83,25 +83,26 @@ int round_num(double a)
double Decolor::energyCalcu(vector <double> &Cg, vector < vector <double> > &polyGrad, vector <double> &wei) double Decolor::energyCalcu(vector <double> &Cg, vector < vector <double> > &polyGrad, vector <double> &wei)
{ {
vector <double> energy; const size_t size = polyGrad[0].size();
vector <double> temp; vector <double> energy(size);
vector <double> temp1; vector <double> temp(size);
vector <double> temp1(size);
double val = 0.0; double val = 0.0;
for(unsigned int i=0;i< polyGrad[0].size();i++) for(size_t i=0;i< polyGrad[0].size();i++)
{ {
val = 0.0; val = 0.0;
for(unsigned int j =0;j<polyGrad.size();j++) for(size_t j =0;j<polyGrad.size();j++)
val = val + (polyGrad[j][i] * wei[j]); val = val + (polyGrad[j][i] * wei[j]);
temp.push_back(val - Cg[i]); temp[i] = val - Cg[i];
temp1.push_back(val + Cg[i]); temp1[i] = val + Cg[i];
} }
for(unsigned int i=0;i<polyGrad[0].size();i++) for(size_t i=0;i<polyGrad[0].size();i++)
energy.push_back(-1.0*log(exp(-1.0*pow(temp[i],2)/sigma) + exp(-1.0*pow(temp1[i],2)/sigma))); energy[i] = -1.0*log(exp(-1.0*pow(temp[i],2)/sigma) + exp(-1.0*pow(temp1[i],2)/sigma));
double sum = 0.0; double sum = 0.0;
for(unsigned int i=0;i<polyGrad[0].size();i++) for(size_t i=0;i<polyGrad[0].size();i++)
sum +=energy[i]; sum +=energy[i];
return (sum/polyGrad[0].size()); return (sum/polyGrad[0].size());
...@@ -120,16 +121,16 @@ void Decolor::init() ...@@ -120,16 +121,16 @@ void Decolor::init()
sigma = 0.02f; sigma = 0.02f;
} }
vector<double> Decolor::product(vector < vector<int> > &comb, vector <double> &initRGB) vector<double> Decolor::product(vector <Vec3i> &comb, const double initRGB[3])
{ {
vector <double> res; vector <double> res(comb.size());
double dp; double dp;
for (unsigned int i=0;i<comb.size();i++) for (size_t i=0;i<comb.size();i++)
{ {
dp = 0.0; dp = 0.0;
for(int j=0;j<3;j++) for(int j=0;j<3;j++)
dp = dp + (comb[i][j] * initRGB[j]); dp = dp + (comb[i][j] * initRGB[j]);
res.push_back(dp); res[i] = dp;
} }
return res; return res;
} }
...@@ -156,8 +157,8 @@ void Decolor::singleChannelGrady(const Mat &img, Mat& dest) ...@@ -156,8 +157,8 @@ void Decolor::singleChannelGrady(const Mat &img, Mat& dest)
void Decolor::gradvector(const Mat &img, vector <double> &grad) void Decolor::gradvector(const Mat &img, vector <double> &grad)
{ {
Mat dest= Mat(img.size().height,img.size().width, CV_32FC1); Mat dest;
Mat dest1= Mat(img.size().height,img.size().width, CV_32FC1); Mat dest1;
singleChannelGradx(img,dest); singleChannelGradx(img,dest);
singleChannelGrady(img,dest1); singleChannelGrady(img,dest1);
...@@ -167,21 +168,22 @@ void Decolor::gradvector(const Mat &img, vector <double> &grad) ...@@ -167,21 +168,22 @@ void Decolor::gradvector(const Mat &img, vector <double> &grad)
int height = d_trans.size().height; int height = d_trans.size().height;
int width = d_trans.size().width; int width = d_trans.size().width;
grad.resize(width * height * 2);
for(int i=0;i<height;i++) for(int i=0;i<height;i++)
for(int j=0;j<width;j++) for(int j=0;j<width;j++)
grad.push_back(d_trans.at<float>(i,j)); grad[i*height + j] = d_trans.at<float>(i, j);
const int offset = width * height;
for(int i=0;i<height;i++) for(int i=0;i<height;i++)
for(int j=0;j<width;j++) for(int j=0;j<width;j++)
grad.push_back(d1_trans.at<float>(i,j)); grad[offset + i * height + j] = d1_trans.at<float>(i, j);
dest.release();
dest1.release();
} }
void Decolor::colorGrad(Mat img, vector <double> &Cg) void Decolor::colorGrad(Mat img, vector <double> &Cg)
{ {
Mat lab = Mat(img.size(),CV_32FC3); Mat lab;
cvtColor(img,lab,COLOR_BGR2Lab); cvtColor(img,lab,COLOR_BGR2Lab);
...@@ -196,32 +198,24 @@ void Decolor::colorGrad(Mat img, vector <double> &Cg) ...@@ -196,32 +198,24 @@ void Decolor::colorGrad(Mat img, vector <double> &Cg)
gradvector(lab_channel[1],Ima); gradvector(lab_channel[1],Ima);
gradvector(lab_channel[2],Imb); gradvector(lab_channel[2],Imb);
Cg.resize(ImL.size());
double res =0.0; double res =0.0;
for(unsigned int i=0;i<ImL.size();i++) for(size_t i=0;i<ImL.size();i++)
{ {
res=sqrt(pow(ImL[i],2) + pow(Ima[i],2) + pow(Imb[i],2))/100; res=sqrt(pow(ImL[i],2) + pow(Ima[i],2) + pow(Imb[i],2))/100;
Cg.push_back(res); Cg[i] = res;
} }
ImL.clear();
Ima.clear();
Imb.clear();
} }
void Decolor::add_vector(vector < vector <int> > &comb, int &idx, int r,int g,int b) void Decolor::add_vector(vector <Vec3i> &comb, int &idx, int r,int g,int b)
{ {
comb.push_back( vector <int>() ); comb.push_back(Vec3i(r, g, b));
comb.at(idx).push_back( r );
comb.at(idx).push_back( g );
comb.at(idx).push_back( b );
idx++; idx++;
} }
void Decolor::add_to_vector_poly(vector < vector <double> > &polyGrad, vector <double> &curGrad, int &idx1) void Decolor::add_to_vector_poly(vector < vector <double> > &polyGrad, vector <double> &curGrad, int &idx1)
{ {
polyGrad.push_back( vector <double>() ); polyGrad.push_back(curGrad);
for(unsigned int i=0;i<curGrad.size();i++)
polyGrad.at(idx1).push_back(curGrad[i]);
idx1++; idx1++;
} }
...@@ -241,51 +235,53 @@ void Decolor::weak_order(Mat img, vector <double> &alf) ...@@ -241,51 +235,53 @@ void Decolor::weak_order(Mat img, vector <double> &alf)
split(img,rgb_channel); split(img,rgb_channel);
vector <double> Rg, Gg, Bg; vector <double> Rg, Gg, Bg;
vector <double> t1, t2, t3;
vector <double> tmp1, tmp2, tmp3;
gradvector(rgb_channel[2],Rg); gradvector(rgb_channel[2],Rg);
gradvector(rgb_channel[1],Gg); gradvector(rgb_channel[1],Gg);
gradvector(rgb_channel[0],Bg); gradvector(rgb_channel[0],Bg);
vector <double> t1(Rg.size()), t2(Rg.size()), t3(Rg.size());
vector <double> tmp1(Rg.size()), tmp2(Rg.size()), tmp3(Rg.size());
double level = .05; double level = .05;
for(unsigned int i=0;i<Rg.size();i++) for(unsigned int i=0;i<Rg.size();i++)
{ {
if(Rg[i] > level) if(Rg[i] > level)
t1.push_back(1.0); t1[i] = 1.0;
else else
t1.push_back(0.0); t1[i] = 0.0;
if(Gg[i] > level) if(Gg[i] > level)
t2.push_back(1.0); t2[i] = 1.0;
else else
t2.push_back(0.0); t2[i] = 0.0;
if(Bg[i] > level) if(Bg[i] > level)
t3.push_back(1.0); t3[i] = 1.0;
else else
t3.push_back(0.0); t3[i] = 0.0;
if(Rg[i] < -1.0*level) if(Rg[i] < -1.0*level)
tmp1.push_back(1.0); tmp1[i] = 1.0;
else else
tmp1.push_back(0.0); tmp1[i] = 0.0;
if(Gg[i] < -1.0*level) if(Gg[i] < -1.0*level)
tmp2.push_back(1.0); tmp2[i] = 1.0;
else else
tmp2.push_back(0.0); tmp2[i] = 0.0;
if(Bg[i] < -1.0*level) if(Bg[i] < -1.0*level)
tmp3.push_back(1.0); tmp3[i] = 1.0;
else else
tmp3.push_back(0.0); tmp3[i] = 0.0;
} }
for(unsigned int i =0 ;i < Rg.size();i++)
alf.push_back(t1[i] * t2[i] * t3[i]);
for(unsigned int i =0 ;i < Rg.size();i++) alf.resize(Rg.size());
for(size_t i =0 ;i < Rg.size();i++)
alf[i] = (t1[i] * t2[i] * t3[i]);
for(size_t i =0 ;i < Rg.size();i++)
alf[i] -= tmp1[i] * tmp2[i] * tmp3[i]; alf[i] -= tmp1[i] * tmp2[i] * tmp3[i];
double sum =0.0; double sum =0.0;
...@@ -300,7 +296,7 @@ void Decolor::weak_order(Mat img, vector <double> &alf) ...@@ -300,7 +296,7 @@ void Decolor::weak_order(Mat img, vector <double> &alf)
} }
void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad, void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad,
vector < double > &Cg, vector < vector <int> >& comb) vector < double > &Cg, vector <Vec3i>& comb)
{ {
int h = img.size().height; int h = img.size().height;
int w = img.size().width; int w = img.size().width;
...@@ -363,19 +359,16 @@ void Decolor::wei_update_matrix(vector < vector <double> > &poly, vector <double ...@@ -363,19 +359,16 @@ void Decolor::wei_update_matrix(vector < vector <double> > &poly, vector <double
} }
void Decolor::wei_inti(vector < vector <int> > &comb, vector <double> &wei) void Decolor::wei_inti(vector <Vec3i> &comb, vector <double> &wei)
{ {
vector <double> initRGB; double initRGB[3] = { .33, .33, .33 };
initRGB.push_back( .33 );
initRGB.push_back( .33 );
initRGB.push_back( .33 );
wei = product(comb,initRGB); wei = product(comb,initRGB);
vector <int> sum; vector <int> sum(comb.size());
for(unsigned int i=0;i<comb.size();i++) for(unsigned int i=0;i<comb.size();i++)
sum.push_back(comb[i][0] + comb[i][1] + comb[i][2]); sum[i] = (comb[i][0] + comb[i][1] + comb[i][2]);
for(unsigned int i=0;i<sum.size();i++) for(unsigned int i=0;i<sum.size();i++)
{ {
...@@ -385,7 +378,6 @@ void Decolor::wei_inti(vector < vector <int> > &comb, vector <double> &wei) ...@@ -385,7 +378,6 @@ void Decolor::wei_inti(vector < vector <int> > &comb, vector <double> &wei)
wei[i] = wei[i] * double(0); wei[i] = wei[i] * double(0);
} }
initRGB.clear();
sum.clear(); sum.clear();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment