Skip to content

Commit 67cfd2c

Browse files
committed
add Filter Solver for Variational Models
improve the performance a little bit
1 parent 3cb53c7 commit 67cfd2c

File tree

2 files changed

+36
-32
lines changed

2 files changed

+36
-32
lines changed

DM.h

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class DM
3333
void Filter(int Type, double & time, int ItNum = 10);//with split
3434
void FilterNoSplit(int Type, double & time, int ItNum = 10);//direct on imgF
3535
/******************* generic solver for variational models *****************************/
36-
void Solver(int Type, double & time, int ItNum, float lambda = 2, float DataFitOrder = 1);
36+
void Solver(int Type, double & time, int MaxItNum, float lambda = 2, float DataFitOrder = 1);
3737

3838
private:
3939
//padded original, tmp, result
@@ -190,7 +190,6 @@ void DM::write(const char* FileName)
190190
//compute Total Variation
191191
void DM::TV(Mat & imgF, Mat & T)
192192
{
193-
T = Mat::zeros(imgF.rows, imgF.cols, CV_32FC1);
194193
float * p_row, *pn_row;
195194
float * p_t;
196195
for(int i = 1; i < imgF.rows-1; i++)
@@ -226,7 +225,7 @@ void DM::MC(Mat& imgF, Mat & MC)
226225
Iyy = pn_row[j] -2*p_row[j] + pp_row[j];
227226

228227
num = Ixx + Iyy;
229-
den = (1.0 + Ix*Ix + Iy*Iy);
228+
den = (1.0f + Ix*Ix + Iy*Iy);
230229
p_d[j] = num/den;
231230
}
232231
}
@@ -254,8 +253,8 @@ void DM::GC(Mat & imgF, Mat &GC)
254253
Ixy = (pn_row[j-1] - pn_row[j+1]- pp_row[j-1] + pp_row[j+1])/4;
255254

256255
num = Ixx*Iyy - Ixy*Ixy;
257-
den = (1.0 + Ix*Ix + Iy*Iy);
258-
den = pow(den, 1.5f);
256+
den = (1.0f + Ix*Ix + Iy*Iy);
257+
den = powf(den, 1.5f);
259258
p_d[j] = num/den;
260259
}
261260
}
@@ -356,7 +355,7 @@ void DM::Filter(int Type, double & time, int ItNum )
356355
return;
357356
}
358357
}
359-
float d;
358+
360359
Tstart = clock();
361360
for(int it=0;it<ItNum;++it)
362361
{
@@ -496,17 +495,19 @@ void DM::FilterNoSplit(int Type, double & time, int ItNum )
496495

497496
//generic filter solver for variational model |U - I|^DataFitOrder + lambda * Regularization
498497
//the DataFitOrder can be fractional such as 1.5, which is not possible for other solvers.
499-
void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitOrder)
498+
void DM::Solver(int Type, double & time, int MaxItNum, float lambda, float DataFitOrder)
500499
{
501500
clock_t Tstart, Tend;
502501
float (DM::* Local)(int i, float* p_pre, float* p, float* p_nex);
503502
void (DM::* curvature_compute)(Mat& img, Mat& curv);
504503

505504
Mat curvature = Mat::zeros(M, N, CV_32FC1);
506505
Mat dataFit = Mat::zeros(M, N, CV_32FC1);
507-
std::vector<float> energyRecord;
506+
std::vector<double> energyRecord;
508507

509-
std::cout<<"Solver with Lambda = "<<lambda<<" and data fit order = "<<DataFitOrder<<endl;
508+
std::cout<<"********************************************"<<endl;
509+
std::cout<<"*** Filter Solver for Variational Models ***\n Lambda = "<<lambda<<" and DataFitOrder = "<<DataFitOrder<<endl;
510+
std::cout<<"********************************************"<<endl;
510511

511512
switch(Type)
512513
{
@@ -543,15 +544,18 @@ void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitO
543544
}
544545

545546
float d, energy_increase, tmp;
547+
int count = 0;
546548

547549
Tstart = clock();
548-
for(int it=0;it<ItNum;++it)
550+
for(int it=0;it<MaxItNum;++it)
549551
{
550552
(this->*curvature_compute)(imgF, curvature);
551553

552554
dataFit = imgF - image;
553-
554555
energyRecord.push_back(lambda*energy(curvature)+DataFitEnergy(dataFit,DataFitOrder));
556+
//if the energy starts to increase, stop the loop
557+
if(count>1 && energyRecord[it] > energyRecord[it-1]) break;
558+
555559
//black circle
556560
for (int i = 1; i < M-1; ++i,++i)
557561
{
@@ -563,7 +567,7 @@ void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitO
563567
{
564568
d = (this->*Local)(j,p_pre,p,p_down);
565569
tmp = fabsf(p[j] - p_data[j]);
566-
energy_increase = pow(tmp + d, DataFitOrder) - pow(tmp, DataFitOrder);
570+
energy_increase = powf(tmp + d, DataFitOrder) - powf(tmp, DataFitOrder);
567571
if (energy_increase < lambda*abs(d)) p[j] += d;
568572
}
569573
}
@@ -579,7 +583,7 @@ void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitO
579583
{
580584
d = (this->*Local)(j,p_pre,p,p_down);
581585
tmp = fabsf(p[j] - p_data[j]);
582-
energy_increase = pow(tmp + d, DataFitOrder) - pow(tmp, DataFitOrder);
586+
energy_increase = powf(tmp + d, DataFitOrder) - powf(tmp, DataFitOrder);
583587
if (energy_increase < lambda*abs(d)) p[j] += d;
584588
}
585589
}
@@ -595,7 +599,7 @@ void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitO
595599
{
596600
d = (this->*Local)(j,p_pre,p,p_down);
597601
tmp = fabsf(p[j] - p_data[j]);
598-
energy_increase = pow(tmp + d, DataFitOrder) - pow(tmp, DataFitOrder);
602+
energy_increase = powf(tmp + d, DataFitOrder) - powf(tmp, DataFitOrder);
599603
if (energy_increase < lambda*abs(d)) p[j] += d;
600604
}
601605
}
@@ -611,10 +615,11 @@ void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitO
611615
{
612616
d = (this->*Local)(j,p_pre,p,p_down);
613617
tmp = fabsf(p[j] - p_data[j]);
614-
energy_increase = pow(tmp + d, DataFitOrder) - pow(tmp, DataFitOrder);
618+
energy_increase = powf(tmp + d, DataFitOrder) - powf(tmp, DataFitOrder);
615619
if (energy_increase < lambda*abs(d)) p[j] += d;
616620
}
617621
}
622+
count++;
618623
}
619624
Tend = clock() - Tstart;
620625
time = double(Tend)/(CLOCKS_PER_SEC/1000.0);
@@ -626,11 +631,10 @@ void DM::Solver(int Type, double & time, int ItNum, float lambda, float DataFitO
626631
//output the total energy profile
627632
ofstream energyProfile;
628633
energyProfile.open ("TotalEnergy.txt");
629-
for (int i = 0; i < ItNum; ++i)
634+
for (int i = 0; i <= count; ++i)
630635
{
631636
energyProfile<<i<<" "<<energyRecord[i]<<endl;
632637
}
633-
energyProfile<<ItNum<<" "<<energyRecord[ItNum];
634638
energyProfile.close();
635639
}
636640

@@ -707,8 +711,8 @@ inline void DM::MC_one(float* __restrict p, float* __restrict p_right, float* __
707711
{
708712

709713
dist[4] = p[j]*8;
710-
dist[5] = (p_pre[j]+p_down[j])*2.5 - dist[4];
711-
dist[6] = (p_right[j-1]+p_right[j])*2.5 - dist[4];
714+
dist[5] = (p_pre[j]+p_down[j])*2.5f - dist[4];
715+
dist[6] = (p_right[j-1]+p_right[j])*2.5f - dist[4];
712716

713717
dist[0] = dist[5] + p_right[j]*5 -p_Corner[j]-p_rd[j];
714718
dist[1] = dist[5] + p_right[j-1]*5 -p_Corner[j-1]-p_rd[j-1];
@@ -732,8 +736,8 @@ inline void DM::MC_two(float* __restrict p, float* __restrict p_right, float* __
732736
{
733737

734738
dist[4] = p[j]*8;
735-
dist[5] = (p_pre[j]+p_down[j])*2.5 - dist[4];
736-
dist[6] = (p_right[j]+p_right[j+1])*2.5 - dist[4];
739+
dist[5] = (p_pre[j]+p_down[j])*2.5f - dist[4];
740+
dist[6] = (p_right[j]+p_right[j+1])*2.5f - dist[4];
737741

738742

739743
dist[0] = dist[5] + p_right[j]*5 -p_Corner[j]-p_rd[j];
@@ -909,7 +913,7 @@ inline void DM::TV_two(float* __restrict p, float* __restrict p_right, float* __
909913
inline void DM::DC_one(float* __restrict p, float* __restrict p_right, float* __restrict p_down, float * __restrict p_rd, float* __restrict p_pre, float* __restrict p_Corner)
910914
{
911915
register float dist[4];
912-
register float weight = -0.225603;
916+
register float weight = -0.225603f;
913917

914918
for (int j = 1; j < N_half; ++j)
915919
{
@@ -933,7 +937,7 @@ inline void DM::DC_one(float* __restrict p, float* __restrict p_right, float* __
933937
inline void DM::DC_two(float* __restrict p, float* __restrict p_right, float* __restrict p_down, float * __restrict p_rd, float* __restrict p_pre, float* __restrict p_Corner)
934938
{
935939
register float dist[4];
936-
register float weight = -0.225603;
940+
register float weight = -0.225603f;
937941

938942
for (int j = 0; j < N_half-1; ++j)
939943
{
@@ -1001,16 +1005,16 @@ inline float DM::Scheme_MC(int i, float* p_pre, float* p, float* p_nex)
10011005
float dist[2];
10021006
float tmp = 8*p[i];
10031007

1004-
dist[0] = 2.5*(p_pre[i]+p_nex[i]) + 5*p[i+1] - p_pre[i+1] - p_nex[i+1] - tmp;
1005-
dist[1] = 2.5*(p_pre[i]+p_nex[i]) + 5*p[i-1] - p_pre[i-1] - p_nex[i-1] - tmp;
1008+
dist[0] = 2.5f*(p_pre[i]+p_nex[i]) + 5*p[i+1] - p_pre[i+1] - p_nex[i+1] - tmp;
1009+
dist[1] = 2.5f*(p_pre[i]+p_nex[i]) + 5*p[i-1] - p_pre[i-1] - p_nex[i-1] - tmp;
10061010
if(fabsf(dist[1])<fabsf(dist[0])) dist[0] = dist[1];
10071011

1008-
dist[1] = 2.5*(p[i-1]+p[i+1]) + 5*p_nex[i] - p_nex[i-1] - p_nex[i+1] - tmp;
1012+
dist[1] = 2.5f*(p[i-1]+p[i+1]) + 5*p_nex[i] - p_nex[i-1] - p_nex[i+1] - tmp;
10091013
if(fabsf(dist[1])<fabsf(dist[0])) dist[0] = dist[1];
1010-
dist[1] = 2.5*(p[i-1]+p[i+1]) + 5*p_pre[i]- p_pre[i-1] - p_pre[i+1] - tmp;
1014+
dist[1] = 2.5f*(p[i-1]+p[i+1]) + 5*p_pre[i]- p_pre[i-1] - p_pre[i+1] - tmp;
10111015
if(fabsf(dist[1])<fabsf(dist[0])) dist[0] = dist[1];
10121016

1013-
dist[0] /= 8.0;
1017+
dist[0] /= 8.0f;
10141018

10151019
return dist[0];
10161020
}
@@ -1095,7 +1099,7 @@ inline float DM::Scheme_TV(int i, float* p_pre, float* p, float* p_nex)
10951099
inline float DM::Scheme_DC(int i, float * __restrict p_pre, float * __restrict p, float * __restrict p_nex)
10961100
{
10971101
float dist[2];
1098-
float weight = -0.225603;
1102+
float weight = -0.225603f;
10991103

11001104
dist[0] = (p_pre[i] + p_nex[i])/2 + (p_pre[i+1] + p_nex[i+1] - 2*p[i+1])*weight - p[i];
11011105
dist[1] = (p_pre[i] + p_nex[i])/2 + (p_pre[i-1] + p_nex[i-1] - 2*p[i-1])*weight - p[i];

main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ using namespace std;
1313
//default filter and iteration number
1414
int ItNum = 10;
1515
int Type = 2;
16-
float lambda = 1;
17-
float DataFitOrder = 1;
16+
float lambda = 1.0f;
17+
float DataFitOrder = 1.0f;
1818

1919
#include "DM.h"
2020

@@ -30,7 +30,7 @@ int main(int argc, char** argv)
3030
cout<<" --------------------------------------------------------------- \n\n";
3131
cout<<"usage: main imageName filterType Iterations.\n For example: ./cf lena.bmp m 30\n";
3232
cout<<" or "<<endl;
33-
cout<<"usage: main imageName filterType Iterations lambda DataFitOrder.\n For example: ./cf lena.bmp m 30 0.2 2\n";
33+
cout<<"usage: main imageName filterType MaxItNum lambda DataFitOrder.\n For example: ./cf lena.bmp m 30 1.2 1.5\n";
3434
cout<<"************************************************\n";
3535
cout<<"Possible Filter Type: t (Total Variation) \n";
3636
cout<<" m (Mean Curvature) \n";

0 commit comments

Comments
 (0)