Xmipp  v3.23.11-Nereus
denoise.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: Carlos Oscar coss@cnb.csic.es (2002)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
26 #include "denoise.h"
27 #include "core/xmipp_program.h"
28 #include "core/histogram.h"
29 #include "data/wavelet.h"
30 
31 // Empty constructor -------------------------------------------------------
33 {
34  DWT_type = "DAUB12";
36  scale = 0;
37  output_scale = 0;
38  threshold = 50;
39  R = -1;
40  SNR0 = 1.0 / 10;
41  SNRF = 1.0 / 5;
42  white_noise = false;
43  adjust_range = true;
44  verbose = 0;
45  dont_denoise = false;
46 }
47 
48 // defineParams -------------------------------------------------------------------s
50 {
51  program->addParamsLine("== Wavelet ==");
52  program->addParamsLine(" [--wavelet <DWT_type=DAUB12> <mode=remove_scale>] : Different types of filters using wavelets");
53  program->addParamsLine(" where <DWT_type>");
54  program->addParamsLine(" DAUB4 DAUB12 DAUB20 : Discrete Wavelet Transform");
55  program->addParamsLine(" where <mode>");
56  program->addParamsLine(" remove_scale");
57  program->addParamsLine(" bayesian <SNR0=0.1> <SNRF=0.2> : Smallest(SNR0) and largest(SNRF) SNR.");
58  program->addParamsLine(" soft_thresholding");
59  program->addParamsLine(" adaptive_soft");
60  program->addParamsLine(" central");
61  program->addParamsLine(" alias -w;");
62  program->addParamsLine(" [--scale+ <s=0>] : scale");
63  program->addParamsLine(" [--output_scale+ <s=0>] : output_scale");
64  program->addParamsLine(" [--th+ <th=50>] : threshold of values (%) to remove");
65  program->addParamsLine(" [-R+ <r=-1>] : Radius to keep, by default half the size");
66  program->addParamsLine(" [--white_noise+] : Select if the noise is white. Used by Bayesian filter.");
67 }
68 
69 // Read from command line --------------------------------------------------
71 {
72 
73  DWT_type = program->getParam("--wavelet", 0);
74  String mode = program->getParam("--wavelet", 1);
75 
76  if (mode == "remove_scale")
78  else if (mode == "soft_thresholding")
80  else if (mode == "bayesian")
81  {
82  SNR0 = program->getDoubleParam("--wavelet", 2);
83  SNRF = program->getDoubleParam("--wavelet", 3);
85  }
86  else if (mode == "adaptive_soft")
88  else if (mode == "central")
90  else
91  REPORT_ERROR(ERR_DEBUG_IMPOSIBLE, "Bad argument type, this couldn't happens, check arguments parser!!!");
92 
93  scale = program->getIntParam("--scale");
94  output_scale = program->getIntParam("--output_scale");
95  threshold = program->getDoubleParam("--th");
96  R = program->getIntParam("-R");
97  white_noise = program->checkParam("--white_noise");
98  verbose = program->verbose;
100 }
101 
102 // Produce side info -------------------------------------------------------
104 {
105  if (DWT_type == "DAUB4")
107  else if (DWT_type == "DAUB12")
109  else if (DWT_type == "DAUB20")
111  else
112  REPORT_ERROR(ERR_VALUE_INCORRECT, "Unknown DWT type");
113 }
114 
115 // Show --------------------------------------------------------------------
117 {
118  if (!verbose)
119  return;
121  std::cout << "DWT type: " << DWT_type << std::endl;
122  std::cout << "Denoising: ";
123  switch (denoising_type)
124  {
125  case REMOVE_SCALE:
126  std::cout << " Remove scale " << scale << std::endl;
127  break;
128  case SOFT_THRESHOLDING:
129  std::cout << " Soft thresholding " << threshold << std::endl;
130  break;
131  case BAYESIAN:
132  std::cout << " Bayesian\n";
133  std::cout << " SNR between " << SNR0 << " and " << SNRF << std::endl
134  << " up to scale " << scale << std::endl;
135  if (white_noise)
136  std::cout << " Imposing white noise\n";
137  break;
138  case ADAPTIVE_SOFT:
139  std::cout << " Adaptive soft thresholding\n";
140  break;
141  case CENTRAL:
142  std::cout << " Keeping central part " << R << " pixels\n";
143  break;
144  }
145  std::cout << "Output scale: " << output_scale << std::endl;
146 }
147 
148 // Denoise volume ----------------------------------------------------------
150 {
151  if (img.getDim()==2)
152  {
153  // 2D image denoising
155  img.rangeAdjust(0, 1);
156 
157  double size2 = log10((double)XSIZE(img)) / log10(2.0);
158  if (ABS(size2 - ROUND(size2)) > 1e-6)
159  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Input image must be of a size power of 2");
160  size2 = log10((double)YSIZE(img)) / log10(2.0);
161  if (ABS(size2 - ROUND(size2)) > 1e-6)
162  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Input image must be of a size power of 2");
163  DWT(img, img);
164  Histogram1D hist;
165  switch (denoising_type)
166  {
167  case REMOVE_SCALE:
168  clean_quadrant2D(img, scale, "01");
169  clean_quadrant2D(img, scale, "10");
170  clean_quadrant2D(img, scale, "11");
171  break;
172  case SOFT_THRESHOLDING:
173  compute_hist(img, hist, 100);
175  break;
176  case BAYESIAN:
179  break;
180  case ADAPTIVE_SOFT:
182  break;
183  case CENTRAL:
184  DWT_keep_central_part(img, R);
185  break;
186  }
187  if (output_scale != 0)
188  {
189  auto reduction = (int)pow(2.0, output_scale);
190  img.resize(YSIZE(img) / reduction, XSIZE(img) / reduction);
191  }
192  IDWT(img, img);
193  }
194  else
195  {
196  // 3D image denoising
197  double size2 = log10((double)XSIZE(img)) / log10(2.0);
198  if (ABS(size2 - ROUND(size2)) > 1e-6)
199  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Input volume must be of a size power of 2");
200  size2 = log10((double)YSIZE(img)) / log10(2.0);
201  if (ABS(size2 - ROUND(size2)) > 1e-6)
202  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Input volume must be of a size power of 2");
203  size2 = log10((double)ZSIZE(img)) / log10(2.0);
204  if (ABS(size2 - ROUND(size2)) > 1e-6)
205  REPORT_ERROR(ERR_MULTIDIM_SIZE, "Input volume must be of a size power of 2");
206 
207  DWT(img, img);
208  Histogram1D hist;
209  switch (denoising_type)
210  {
211  case REMOVE_SCALE:
212  clean_quadrant3D(img, scale, "001");
213  clean_quadrant3D(img, scale, "010");
214  clean_quadrant3D(img, scale, "011");
215  clean_quadrant3D(img, scale, "100");
216  clean_quadrant3D(img, scale, "101");
217  clean_quadrant3D(img, scale, "110");
218  clean_quadrant3D(img, scale, "111");
219  break;
220  case SOFT_THRESHOLDING:
221  compute_hist(img, hist, 100);
223  break;
224  case BAYESIAN:
227  break;
228  case ADAPTIVE_SOFT:
229  std::cout << "Adaptive soft-thresholding not implemented for imgumes\n";
230  break;
231  case CENTRAL:
232  std::cout << "Keep central part not implemented for volumes\n";
233  break;
234  }
235 
236  if (output_scale != 0)
237  {
238  auto reduction = (int)pow(2.0, output_scale);
239  img.resizeNoCopy(ZSIZE(img) / reduction, YSIZE(img) / reduction, XSIZE(img) / reduction);
240  }
241  IDWT(img, img);
242 
243  }
244 }
245 
247 {
248  DWT(vol, vol);
250 
251  if (output_scale != 0)
252  {
253  auto reduction = (int)pow(2.0, output_scale);
254  vol.resizeNoCopy(ZSIZE(vol) / reduction, YSIZE(vol) / reduction, XSIZE(vol) / reduction);
255  }
256  IDWT(vol, vol);
257 }
int output_scale
Definition: denoise.h:75
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
void set_DWT_type(int DWT_type)
Definition: wavelet.cpp:154
static void defineParams(XmippProgram *program)
Definition: denoise.cpp:49
bool dont_denoise
Definition: denoise.h:111
double getDoubleParam(const char *param, int arg=0)
String DWT_type
Definition: denoise.h:52
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
void resizeNoCopy(const MultidimArray< T1 > &v)
Just for debugging, situation that can&#39;t happens.
Definition: xmipp_error.h:120
void clean_quadrant3D(MultidimArray< double > &I, int scale, const std::string &quadrant)
Definition: wavelet.cpp:297
void readParams(XmippProgram *program)
Definition: denoise.cpp:70
bool white_noise
Definition: denoise.h:95
#define DAUB20
Definition: wavelet.h:40
double SNR0
Definition: denoise.h:87
void rangeAdjust(T minF, T maxF)
double percentil(double percent_mass)
Definition: histogram.cpp:160
Incorrect MultidimArray size.
Definition: xmipp_error.h:174
void clean_quadrant2D(MultidimArray< double > &I, int scale, const std::string &quadrant)
Definition: wavelet.cpp:288
Matrix1D< double > bayesian_wiener_filtering2D(MultidimArray< double > &WI, int allowed_scale, double SNR0, double SNRF, bool white_noise, int tell, bool denoise)
Definition: wavelet.cpp:603
double threshold
Definition: denoise.h:79
const char * getParam(const char *param, int arg=0)
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
#define DAUB12
Definition: wavelet.h:39
void DWT(const MultidimArray< T > &v, MultidimArray< double > &result, int isign=1)
Definition: wavelet.h:83
bool adjust_range
Definition: denoise.h:99
void denoiseAvgBayesian(MultidimArray< double > &vol)
Definition: denoise.cpp:246
#define XSIZE(v)
#define DAUB4
Definition: wavelet.h:38
void adaptive_soft_thresholding2D(MultidimArray< double > &I, int scale)
Definition: wavelet.cpp:384
#define ABS(x)
Definition: xmipp_macros.h:142
#define ZSIZE(v)
#define ROUND(x)
Definition: xmipp_macros.h:210
void log10(Image< double > &op)
int verbose
Verbosity level.
void mode
void apply(MultidimArray< double > &img)
Definition: denoise.cpp:149
void produceSideInfo()
Definition: denoise.cpp:103
Matrix1D< double > bayesian_wiener_filtering3D(MultidimArray< double > &WI, int allowed_scale, double SNR0, double SNRF, bool white_noise, int tell, bool denoise)
Definition: wavelet.cpp:726
void show()
Definition: denoise.cpp:116
std::string String
Definition: xmipp_strings.h:34
DenoisingType denoising_type
Definition: denoise.h:59
void DWT_keep_central_part(MultidimArray< double > &I, double R)
Definition: wavelet.cpp:396
void IDWT(const MultidimArray< double > &v, MultidimArray< double > &result)
Definition: wavelet.cpp:159
bool checkParam(const char *param)
void soft_thresholding(MultidimArray< double > &I, double th)
Definition: wavelet.cpp:308
double SNRF
Definition: denoise.h:91
int getIntParam(const char *param, int arg=0)
Incorrect value received.
Definition: xmipp_error.h:195
void addParamsLine(const String &line)
Matrix1D< double > estimatedS
Definition: denoise.h:119