|
1 |
/*
|
|
2 |
Anisotropic blur : removes noise while keeping cell walls
|
|
3 |
Parallel version
|
|
4 |
3D only
|
|
5 |
|
|
6 |
To compile :
|
|
7 |
g++ -o edge_indicator edge_indicator.cpp -O2 -L/usr/X11R6/lib -lm -lpthread -lX11 -fopenmp -l:libtiff.so.4
|
|
8 |
Needs CImg.h
|
|
9 |
|
|
10 |
To execute :
|
|
11 |
./edge_indicator img K sigma [filtertype]
|
|
12 |
|
|
13 |
img : image in .inr or .inr.gz
|
|
14 |
K : proportional to width of cell walls (0.1 - 0.3)
|
|
15 |
sigma : amount of gaussian blur (float)
|
|
16 |
filtertype (optional) : by default 1/(1+x/K) type edge function. If "exp" is marked, then exp(-x/K) edge function is used
|
|
17 |
|
|
18 |
* authors : Annamaria Kiss (RDP)
|
|
19 |
* ENS-Lyon
|
|
20 |
*
|
|
21 |
|
|
22 |
*/
|
|
23 |
#include <iostream>
|
|
24 |
#include <math.h>
|
|
25 |
#include <sstream>
|
|
26 |
#include <fstream>
|
|
27 |
|
|
28 |
#include "CImg.h"
|
|
29 |
#include <omp.h>
|
|
30 |
|
|
31 |
using namespace cimg_library;
|
|
32 |
using namespace std;
|
|
33 |
|
|
34 |
#include "lsm_lib.h"
|
|
35 |
|
|
36 |
//-----------------------------------------------------------------------------
|
|
37 |
//Main
|
|
38 |
//-----------------------------------------------------------------------------
|
|
39 |
int main (int argc, char* argv[])
|
|
40 |
{
|
|
41 |
// double begin_main=omp_get_wtime();
|
|
42 |
|
|
43 |
if(argc<4 || argc>5)
|
|
44 |
{
|
|
45 |
cout<<"!! wrong number of arguments"<<endl;
|
|
46 |
cout<<"how to execute : edge_indicator img K sigma gamma upDiter nbIter [type]"<<endl;
|
|
47 |
cout<<" img : image in .inr or .inr.gz"<<endl;
|
|
48 |
cout<<" K : proportional to width of cell walls (0.1 - 0.3)"<<endl;
|
|
49 |
cout<<" sigma : amount of gaussian blur (float)"<<endl;
|
|
50 |
cout<<" filtertype (optional) : by default 'hill' that is 1/(1+x/K) type edge function. If 'exp' is marked, then exp(-x/K) edge function is used"<<endl;
|
|
51 |
return 0;
|
|
52 |
}
|
|
53 |
|
|
54 |
|
|
55 |
string filter_type="hill";
|
|
56 |
if (argc==5)
|
|
57 |
{
|
|
58 |
if (string(argv[4]).compare("exp")==0)
|
|
59 |
{filter_type="exp";}
|
|
60 |
}
|
|
61 |
|
|
62 |
|
|
63 |
//Open image with name in argument
|
|
64 |
//image is converted to unsigned char (0 to 255) and then to float
|
|
65 |
string name=argv[1];
|
|
66 |
CImg<> img1;
|
|
67 |
CImg<char> description;
|
|
68 |
float tailleVoxel[3] = {0}; // resolution initialisation
|
|
69 |
bool gzipped = false;
|
|
70 |
bool tiffile = false;
|
|
71 |
|
|
72 |
if(name.compare(name.size()-4,4,".inr")==0)
|
|
73 |
{
|
|
74 |
img1.load(name.c_str());
|
|
75 |
img1.get_load_inr(name.c_str(),tailleVoxel); // reads resolution
|
|
76 |
}
|
|
77 |
else if(name.compare(name.size()-7,7,".inr.gz")==0)
|
|
78 |
{
|
|
79 |
gzipped = true;
|
|
80 |
string oldname = name;
|
|
81 |
name.erase(name.size()-3);
|
|
82 |
string zip="gunzip -c "+oldname+" > "+name;
|
|
83 |
if(system(zip.c_str())); // decompress image file
|
|
84 |
img1.load(name.c_str()); //read image
|
|
85 |
img1.get_load_inr(name.c_str(),tailleVoxel); // read resolution
|
|
86 |
zip="rm "+name;
|
|
87 |
if(system(zip.c_str())); //removes decompressed image
|
|
88 |
}
|
|
89 |
else if(name.compare(name.size()-4,4,".tif")==0)
|
|
90 |
{
|
|
91 |
tiffile = true;
|
|
92 |
cout<<"file to read : "<<name<<endl;
|
|
93 |
img1.load_tiff(name.c_str(),0,~0U,1,tailleVoxel,&description);
|
|
94 |
}
|
|
95 |
else
|
|
96 |
{cout<<"!! wrong file extension (not an inr/inr.gz/tif) : "<<name<<endl;
|
|
97 |
return 0;}
|
|
98 |
|
|
99 |
CImg<float> img=img1;
|
|
100 |
img1.assign();
|
|
101 |
cout<<"image : "<<name<<endl;
|
|
102 |
cout<<"gzipped : "<<gzipped<<endl;
|
|
103 |
cout<<"image depth : "<<img.depth()<<endl;
|
|
104 |
if(img.depth()<=1)
|
|
105 |
{
|
|
106 |
cout<<"This is not a 3D image"<<endl;
|
|
107 |
return 0;
|
|
108 |
}
|
|
109 |
//---------------------------------------------------------Parameters
|
|
110 |
float dt=0.1;
|
|
111 |
float K= atof(argv[2]);
|
|
112 |
float sigma=atof(argv[3]);
|
|
113 |
|
|
114 |
cout<<"Voxel size : ("<<tailleVoxel[0]<<","<<tailleVoxel[1]<<","<<tailleVoxel[2]<<")"<<endl;
|
|
115 |
|
|
116 |
//--------------------------------------------------------Name and directories
|
|
117 |
string insert=string("_edgeind-K")+argv[2]+"s"+argv[3]+"-type-"+filter_type;
|
|
118 |
name.insert(name.size()-4,insert);
|
|
119 |
size_t test=name.rfind("/");
|
|
120 |
if(test!=name.npos)
|
|
121 |
{name.erase(0,test+1);}
|
|
122 |
|
|
123 |
//---------------------------------------------------------------------Processing
|
|
124 |
//Evolution during nbIter
|
|
125 |
//-------------------------------------------------------------------------3D
|
|
126 |
cout<<"3D image"<<endl;
|
|
127 |
cout <<"Computing Hessian"<<endl;
|
|
128 |
|
|
129 |
int nthreads;
|
|
130 |
CImg<float> fx;
|
|
131 |
CImg<float> edgeind;
|
|
132 |
|
|
133 |
// make a blur before taking derivatives
|
|
134 |
CImg<float> imgBlur=img.get_blur(sigma);
|
|
135 |
fx=edge_lambda3(imgBlur);
|
|
136 |
|
|
137 |
if (filter_type.compare("hill")==0)
|
|
138 |
{
|
|
139 |
edgeind=edge_indicator3(img,K);
|
|
140 |
}
|
|
141 |
else
|
|
142 |
{
|
|
143 |
edgeind=edge_indicator3exp(img,K);
|
|
144 |
}
|
|
145 |
|
|
146 |
|
|
147 |
float maxi=edgeind.max();
|
|
148 |
float mini=edgeind.min();
|
|
149 |
edgeind=maxi-edgeind;
|
|
150 |
maxi=edgeind.max();
|
|
151 |
mini=edgeind.min();
|
|
152 |
edgeind=edgeind*255./(maxi-mini);
|
|
153 |
//edgeind=(edgeind-maxi)*255./(mini-maxi);
|
|
154 |
|
|
155 |
//Saving results
|
|
156 |
string newname=name;
|
|
157 |
CImg<unsigned char> imgbis=edgeind;
|
|
158 |
//CImg<float> imgbis=edgeind;
|
|
159 |
cout<<"Save image"<<endl;
|
|
160 |
cout<<"image : "<<newname<<endl;
|
|
161 |
if (tiffile)
|
|
162 |
{
|
|
163 |
imgbis.save_tiff(newname.c_str(),0,tailleVoxel,description.data());
|
|
164 |
}
|
|
165 |
else
|
|
166 |
{
|
|
167 |
imgbis.save_inr(newname.c_str(),tailleVoxel);
|
|
168 |
if (gzipped)
|
|
169 |
{
|
|
170 |
string zip="gzip -f "+newname;
|
|
171 |
if(system(zip.c_str()));
|
|
172 |
}
|
|
173 |
}
|
|
174 |
imgbis.assign();
|
|
175 |
|
|
176 |
cout << "Done!"<<endl;
|
|
177 |
|
|
178 |
|
|
179 |
return 0;
|
|
180 |
}
|