Xmipp  v3.23.11-Nereus
Functions
Collaboration diagram for Filters:

Functions

double denoiseTVenergy (double mu, const MultidimArray< double > &X, const MultidimArray< double > &Y, double s, double q, double lambda, double sigmag, double g)
 
void denoiseTVgradient (double mu, const MultidimArray< double > &X, const MultidimArray< double > &Y, double s, double q, double lambda, double sigmag, double g, MultidimArray< double > &gradientI)
 
void denoiseTVproj (const MultidimArray< double > &X, const MultidimArray< double > &Y, double theta, MultidimArray< double > &dold)
 
void denoiseTVFilter (MultidimArray< double > &xnew, int maxIter)
 
void substractBackgroundPlane (MultidimArray< double > &I)
 
void substractBackgroundRollingBall (MultidimArray< double > &I, int radius)
 
void detectBackground (const MultidimArray< double > &vol, MultidimArray< double > &mask, double alpha, double &final_mean)
 
void contrastEnhancement (Image< double > *I)
 
void regionGrowing2D (const MultidimArray< double > &I_in, MultidimArray< double > &I_out, int i, int j, float stop_colour=1, float filling_colour=1, bool less=true, int neighbourhood=8)
 
void distanceTransform (const MultidimArray< int > &in, MultidimArray< int > &out, bool wrap=false)
 
int labelImage2D (const MultidimArray< double > &I, MultidimArray< double > &label, int neighbourhood=8)
 
int labelImage3D (const MultidimArray< double > &V, MultidimArray< double > &label)
 
void removeSmallComponents (MultidimArray< double > &I, int size, int neighbourhood=8)
 
void keepBiggestComponent (MultidimArray< double > &I, double percentage=0, int neighbourhood=8)
 
void fillBinaryObject (MultidimArray< double > &I, int neighbourhood=8)
 
void varianceFilter (MultidimArray< double > &I, int kernelSize=10, bool relative=false)
 
void noisyZonesFilter (MultidimArray< double > &I, int kernelSize=10)
 
double giniCoeff (MultidimArray< double > &I, int varKernelSize=50)
 
double OtsuSegmentation (MultidimArray< double > &V)
 
double EntropySegmentation (MultidimArray< double > &V)
 
double EntropyOtsuSegmentation (MultidimArray< double > &V, double percentil=0.05, bool binarizeVolume=true)
 
template<typename T >
double correlation (const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=nullptr, int l=0, int m=0, int q=0)
 
template<typename T >
double fastMaskedCorrelation (const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > &mask)
 
template<typename T >
double fastCorrentropy (const MultidimArray< T > &x, const MultidimArray< T > &y, double sigma, const GaussianInterpolator &G)
 
template<typename T >
double correntropy (const MultidimArray< T > &x, const MultidimArray< T > &y, double sigma)
 
double bestShift (const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, CorrelationAux &aux, const MultidimArray< int > *mask=nullptr, int maxShift=-1)
 
void bestShift (const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, double &shiftZ, CorrelationAux &aux, const MultidimArray< int > *mask=nullptr)
 
void bestNonwrappingShift (const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, CorrelationAux &aux)
 
double bestShiftRealSpace (const MultidimArray< double > &I1, MultidimArray< double > &I2, double &shiftX, double &shiftY, const MultidimArray< int > *mask=nullptr, int maxShift=5, double shiftStep=1.0)
 
double alignImages (const MultidimArray< double > &Iref, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap=xmipp_transformation::WRAP)
 
double alignImages (const MultidimArray< double > &Iref, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
 
double bestRotationAroundZ (const MultidimArray< double > &Iref, const MultidimArray< double > &I, CorrelationAux &aux, VolumeAlignmentAux &aux2)
 
double alignImagesConsideringMirrors (const MultidimArray< double > &Iref, MultidimArray< double > &I, Matrix2D< double > &M, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3, bool wrap=xmipp_transformation::WRAP, const MultidimArray< int > *mask=NULL)
 
void estimateGaussian2D (const MultidimArray< double > &I, double &a, double &b, Matrix1D< double > &mu, Matrix2D< double > &sigma, bool estimateMu=true, int iterations=10)
 
template<typename T >
double euclidianDistance (const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=nullptr)
 
template<typename T >
double mutualInformation (const MultidimArray< T > &x, const MultidimArray< T > &y, int nx=0, int ny=0, const MultidimArray< int > *mask=nullptr)
 
template<typename T >
double rms (const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=nullptr, MultidimArray< double > *Contributions=nullptr)
 
void fourierBesselDecomposition (const MultidimArray< double > &img_in, double r2, int k1, int k2)
 
template<typename T >
void sort (T a, T b, T c, MultidimArray< T > &v)
 
template<typename T >
void medianFilter3x3 (MultidimArray< T > &m, MultidimArray< T > &out)
 
void smoothingShah (MultidimArray< double > &img, MultidimArray< double > &surface_strength, MultidimArray< double > &edge_strength, const Matrix1D< double > &W, int OuterLoops, int InnerLoops, int RefinementLoops, bool adjust_range=true)
 
double tomographicDiffusion (MultidimArray< double > &V, const Matrix1D< double > &alpha, double lambda)
 
void rotationalInvariantMoments (const MultidimArray< double > &img, const MultidimArray< int > *mask, MultidimArray< double > &v_out)
 
void inertiaMoments (const MultidimArray< double > &img, const MultidimArray< int > *mask, Matrix1D< double > &v_out, Matrix2D< double > &u)
 
void fillTriangle (MultidimArray< double > &img, int *tx, int *ty, double color)
 
void localThresholding (MultidimArray< double > &img, double C, double dimLocal, MultidimArray< int > &result, MultidimArray< int > *mask=nullptr)
 
void centerImageTranslationally (MultidimArray< double > &I, CorrelationAux &aux)
 
void centerImageRotationally (MultidimArray< double > &I, RotationalCorrelationAux &aux)
 
Matrix2D< double > centerImage (MultidimArray< double > &I, CorrelationAux &aux, RotationalCorrelationAux &aux2, int Niter=10, bool limitShift=true)
 
void forcePositive (MultidimArray< double > &V)
 
template<typename T >
void boundMedianFilter (MultidimArray< T > &V, const MultidimArray< char > &mask, int n=0)
 
template<typename T >
void pixelDesvFilter (MultidimArray< T > &V, double thresFactor)
 
template<typename T >
void logFilter (MultidimArray< T > &V, double a, double b, double c)
 
void SmoothResize (byte *srcpic8, byte *destpic8, size_t swide, size_t shigh, size_t dwide, size_t dhigh)
 

Functions for all multidimensional arrays

template<typename T >
double correlationIndex (const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
 

Detailed Description

Function Documentation

◆ alignImages() [1/2]

double alignImages ( const MultidimArray< double > &  Iref,
MultidimArray< double > &  I,
Matrix2D< double > &  M,
bool  wrap = xmipp_transformation::WRAP 
)

Align two images

This function modifies I to be aligned with Iref. Translational and rotational alignments are both considered. The matrix transforming I into Iref is returned.

The function returns the correlation between the two aligned images.

Definition at line 2141 of file filters.cpp.

2143 {
2144  AlignmentAux aux;
2145  CorrelationAux aux2;
2147  return alignImages(Iref, I, M, wrap, aux, aux2, aux3);
2148 }
double alignImages(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
Definition: filters.cpp:2047

◆ alignImages() [2/2]

double alignImages ( const MultidimArray< double > &  Iref,
MultidimArray< double > &  I,
Matrix2D< double > &  M,
bool  wrap,
AlignmentAux aux,
CorrelationAux aux2,
RotationalCorrelationAux aux3 
)

Fast version of align two images

Definition at line 2131 of file filters.cpp.

2134 {
2135  Iref.checkDimension(2);
2136  AlignmentTransforms IrefTransforms;
2137  computeAlignmentTransforms(Iref,IrefTransforms, aux, aux2);
2138  return alignImages(Iref, IrefTransforms, I, M, wrap, aux, aux2, aux3);
2139 }
double alignImages(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, bool wrap, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3)
Definition: filters.cpp:2047
void computeAlignmentTransforms(const MultidimArray< double > &I, AlignmentTransforms &ITransforms, AlignmentAux &aux, CorrelationAux &aux2)
Definition: filters.cpp:2035

◆ alignImagesConsideringMirrors()

double alignImagesConsideringMirrors ( const MultidimArray< double > &  Iref,
MultidimArray< double > &  I,
Matrix2D< double > &  M,
AlignmentAux aux,
CorrelationAux aux2,
RotationalCorrelationAux aux3,
bool  wrap = xmipp_transformation::WRAP,
const MultidimArray< int > *  mask = NULL 
)

Align two images considering also the mirrors

This function modifies I to be aligned with Iref. Translational and rotational alignments are both considered. The correlation coefficient between I transformed and Iref is returned. A mask can be supplied for computing this correlation.

Definition at line 2189 of file filters.cpp.

2193 {
2194  AlignmentTransforms IrefTransforms;
2195  computeAlignmentTransforms(Iref,IrefTransforms, aux, aux2);
2196  return alignImagesConsideringMirrors(Iref, IrefTransforms, I, M, aux, aux2, aux3, wrap, mask);
2197 }
void computeAlignmentTransforms(const MultidimArray< double > &I, AlignmentTransforms &ITransforms, AlignmentAux &aux, CorrelationAux &aux2)
Definition: filters.cpp:2035
double alignImagesConsideringMirrors(const MultidimArray< double > &Iref, const AlignmentTransforms &IrefTransforms, MultidimArray< double > &I, Matrix2D< double > &M, AlignmentAux &aux, CorrelationAux &aux2, RotationalCorrelationAux &aux3, bool wrap, const MultidimArray< int > *mask)
Definition: filters.cpp:2150

◆ bestNonwrappingShift()

void bestNonwrappingShift ( const MultidimArray< double > &  I1,
const MultidimArray< double > &  I2,
double &  shiftX,
double &  shiftY,
CorrelationAux aux 
)

Translational search (non-wrapping)

This function returns the best interpolated shift for the alignment of two images. You can restrict the shift to a region defined by a mask (the maximum will be sought where the mask is 1).

Definition at line 1895 of file filters.cpp.

1898 {
1900  bestNonwrappingShift(I1,aux.FFT1,I2,shiftX,shiftY,aux);
1901 }
FourierTransformer transformer1
Definition: xmipp_fftw.h:555
void bestNonwrappingShift(const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, CorrelationAux &aux)
Definition: filters.cpp:1895
MultidimArray< std::complex< double > > FFT1
Definition: xmipp_fftw.h:554
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166

◆ bestRotationAroundZ()

double bestRotationAroundZ ( const MultidimArray< double > &  Iref,
const MultidimArray< double > &  I,
CorrelationAux aux,
VolumeAlignmentAux aux2 
)

Align two volumes by applying a rotation around Z. The rotation must be applied on I to get Iref.

Definition at line 2356 of file filters.cpp.

2359 {
2360  Iref.checkDimension(3);
2361  I.checkDimension(3);
2362  if (!I.sameShape(Iref))
2364  "Both volumes should be of the same shape");
2365 
2366  double deltaAng = atan(2.0 / XSIZE(I));
2367  Matrix1D<double> v(3);
2368  XX(v) = 0;
2369  YY(v) = 0;
2370  ZZ(v) = 1;
2371  volume_convertCartesianToCylindrical(Iref, aux2.IrefCyl, 3, XSIZE(I) / 2, 1,
2372  0, 2 * PI, deltaAng, v);
2373  return fastBestRotationAroundZ(aux2.IrefCyl, I, aux, aux2);
2374 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
double fastBestRotationAroundZ(const MultidimArray< double > &IrefCyl, const MultidimArray< double > &I, CorrelationAux &aux, VolumeAlignmentAux &aux2)
Definition: filters.cpp:2276
Incorrect MultidimArray size.
Definition: xmipp_error.h:174
#define XX(v)
Definition: matrix1d.h:85
bool sameShape(const MultidimArrayBase &op) const
#define XSIZE(v)
#define YY(v)
Definition: matrix1d.h:93
MultidimArray< double > IrefCyl
Definition: filters.h:570
#define PI
Definition: tools.h:43
#define ZZ(v)
Definition: matrix1d.h:101
void volume_convertCartesianToCylindrical(const MultidimArray< double > &in, MultidimArray< double > &out, double Rmin, double Rmax, double deltaR, float angMin, double angMax, float deltaAng, Matrix1D< double > &axis)
Definition: polar.cpp:305

◆ bestShift() [1/2]

double bestShift ( const MultidimArray< double > &  I1,
const MultidimArray< double > &  I2,
double &  shiftX,
double &  shiftY,
CorrelationAux aux,
const MultidimArray< int > *  mask = nullptr,
int  maxShift = -1 
)

Translational search

This function returns the best interpolated shift for the alignment of two images. You can restrict the shift to a region defined by a mask (the maximum will be sought where the mask is 1).

To apply these results you must shift I1 by (-shiftX,-shiftY) or I2 by (shiftX, shiftY).

You can limit the maximum achievable shift by using maxShift. If it is set to -1, any shift is valid.

The function returns the maximum correlation found.

Definition at line 1735 of file filters.cpp.

1738 {
1740  return bestShift(I1,aux.FFT1,I2,shiftX,shiftY,aux,mask,maxShift);
1741 }
FourierTransformer transformer1
Definition: xmipp_fftw.h:555
MultidimArray< std::complex< double > > FFT1
Definition: xmipp_fftw.h:554
void FourierTransform(T &v, T1 &V, bool getCopy=true)
Definition: xmipp_fftw.h:166
template float bestShift(MultidimArray< float > &, float &, float &, const MultidimArray< int > *, int)

◆ bestShift() [2/2]

void bestShift ( const MultidimArray< double > &  I1,
const MultidimArray< double > &  I2,
double &  shiftX,
double &  shiftY,
double &  shiftZ,
CorrelationAux aux,
const MultidimArray< int > *  mask = nullptr 
)

Translational search (3D)

This function returns the best interpolated shift for the alignment of two volumes. You can restrict the shift to a region defined by a mask (the maximum will be sought where the mask is 1).

To apply these results you must shift I1 by (-shiftX,-shiftY,-shiftZ) or I2 by (shiftX, shiftY,shiftZ).

Definition at line 1755 of file filters.cpp.

1758 {
1759  I1.checkDimension(3);
1760  I2.checkDimension(3);
1761 
1762  int imax;
1763  int jmax;
1764  int kmax;
1765  int i_actual;
1766  int j_actual;
1767  int k_actual;
1768  double max;
1769  double xmax;
1770  double ymax;
1771  double zmax;
1772  double sumcorr;
1773  double avecorr;
1774  double stdcorr;
1775  double dummy;
1776  bool neighbourhood = true;
1777  MultidimArray<double> Mcorr;
1778 
1779  correlation_matrix(I1, I2, Mcorr, aux);
1780 
1781  /*
1782  Warning: for masks with a small number of non-zero pixels, this routine is NOT reliable...
1783  Anyway, maybe using a mask is not a good idea at al...
1784  */
1785 
1786  // Adjust statistics within shiftmask to average 0 and stddev 1
1787  if (mask != nullptr)
1788  {
1789  if ((*mask).sum() < 2)
1790  {
1791  shiftX = shiftY = shiftZ = 0.;
1792  return;
1793  }
1794  else
1795  {
1796  computeStats_within_binary_mask(*mask, Mcorr, dummy, dummy, avecorr,
1797  stdcorr);
1798  double istdcorr = 1.0 / stdcorr;
1800  if (DIRECT_MULTIDIM_ELEM(*mask, n))
1801  DIRECT_MULTIDIM_ELEM(Mcorr, n) =
1802  (DIRECT_MULTIDIM_ELEM(Mcorr, n) - avecorr)
1803  * istdcorr;
1804  else
1805  DIRECT_MULTIDIM_ELEM(Mcorr, n) = 0.;
1806  }
1807  }
1808  else
1809  Mcorr.statisticsAdjust(0., 1.);
1810  Mcorr.maxIndex(kmax, imax, jmax);
1811  max = A3D_ELEM(Mcorr, kmax, imax, jmax);
1812 
1813  // Estimate n_max around the maximum
1814  int n_max = -1;
1815  while (neighbourhood)
1816  {
1817  n_max++;
1818  for (int k = -n_max; k <= n_max && neighbourhood; k++)
1819  {
1820  k_actual = k + kmax;
1821  if (k_actual < STARTINGZ(Mcorr) || k_actual > FINISHINGZ(Mcorr))
1822  {
1823  neighbourhood = false;
1824  break;
1825  }
1826  for (int i = -n_max; i <= n_max && neighbourhood; i++)
1827  {
1828  i_actual = i + imax;
1829  if (i_actual < STARTINGY(Mcorr) || i_actual > FINISHINGY(Mcorr))
1830  {
1831  neighbourhood = false;
1832  break;
1833  }
1834  for (int j = -n_max; j <= n_max && neighbourhood; j++)
1835  {
1836  j_actual = j + jmax;
1837  if (j_actual < STARTINGX(Mcorr)
1838  || j_actual > FINISHINGX(Mcorr))
1839  {
1840  neighbourhood = false;
1841  break;
1842  }
1843  else if (max
1844  / 1.414 > A3D_ELEM(Mcorr, k_actual, i_actual, j_actual))
1845  {
1846  neighbourhood = false;
1847  break;
1848  }
1849  }
1850  }
1851  }
1852  }
1853 
1854  // We have the neighbourhood => looking for the gravity centre
1855  zmax = xmax = ymax = sumcorr = 0.;
1856  if (kmax-n_max<STARTINGZ(Mcorr))
1857  n_max=std::min(kmax-STARTINGZ(Mcorr),n_max);
1858  if (kmax+n_max>FINISHINGZ(Mcorr))
1859  n_max=std::min(FINISHINGZ(Mcorr)-kmax,n_max);
1860  if (imax-n_max<STARTINGY(Mcorr))
1861  n_max=std::min(imax-STARTINGY(Mcorr),n_max);
1862  if (imax+n_max>FINISHINGY(Mcorr))
1863  n_max=std::min(FINISHINGY(Mcorr)-imax,n_max);
1864  if (jmax-n_max<STARTINGY(Mcorr))
1865  n_max=std::min(jmax-STARTINGX(Mcorr),n_max);
1866  if (jmax+n_max>FINISHINGY(Mcorr))
1867  n_max=std::min(FINISHINGX(Mcorr)-jmax,n_max);
1868  for (int k = -n_max; k <= n_max; k++)
1869  {
1870  k_actual = k + kmax;
1871  for (int i = -n_max; i <= n_max; i++)
1872  {
1873  i_actual = i + imax;
1874  for (int j = -n_max; j <= n_max; j++)
1875  {
1876  j_actual = j + jmax;
1877  double val = A3D_ELEM(Mcorr, k_actual, i_actual, j_actual);
1878  zmax += k_actual * val;
1879  ymax += i_actual * val;
1880  xmax += j_actual * val;
1881  sumcorr += val;
1882  }
1883  }
1884  }
1885  if (sumcorr != 0)
1886  {
1887  shiftX = xmax / sumcorr;
1888  shiftY = ymax / sumcorr;
1889  shiftZ = zmax / sumcorr;
1890  }
1891 }
void min(Image< double > &op1, const Image< double > &op2)
#define FINISHINGX(v)
void correlation_matrix(const MultidimArray< double > &m1, const MultidimArray< double > &m2, MultidimArray< double > &R, CorrelationAux &aux, bool center)
Definition: xmipp_fftw.cpp:869
void maxIndex(int &jmax) const
#define FINISHINGZ(v)
#define STARTINGX(v)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void computeStats_within_binary_mask(const MultidimArray< T1 > &mask, const MultidimArray< T > &m, double &min_val, double &max_val, double &avg, double &stddev)
Definition: mask.h:799
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
double dummy
#define j
#define FINISHINGY(v)
#define STARTINGZ(v)
int * n
void statisticsAdjust(U avgF, U stddevF)

◆ bestShiftRealSpace()

double bestShiftRealSpace ( const MultidimArray< double > &  I1,
MultidimArray< double > &  I2,
double &  shiftX,
double &  shiftY,
const MultidimArray< int > *  mask = nullptr,
int  maxShift = 5,
double  shiftStep = 1.0 
)

Translational search (non-wrapping).

Search is performed in real-space

Definition at line 1989 of file filters.cpp.

1992 {
1993  I1.checkDimension(2);
1994  I2.checkDimension(2);
1995 
1996  double bestCorr=-1e38;
1997 
1998  MultidimArray<double> alignedI2;
1999  MultidimArray<double> bestI2;
2000  int maxShift2=maxShift*maxShift;
2001  Matrix1D<double> shift(2);
2002  for (double y=-maxShift; y<=maxShift; y+=shiftStep)
2003  for (double x=-maxShift; x<=maxShift; x+=shiftStep)
2004  {
2005  if (y*y+x*x>maxShift2)
2006  continue;
2007  YY(shift)=y;
2008  XX(shift)=x;
2009  translate(xmipp_transformation::LINEAR,alignedI2,I2,shift,xmipp_transformation::DONT_WRAP,0.0);
2010 
2011  double corr=correlationIndex(I1,alignedI2,mask);
2012  if (corr>bestCorr)
2013  {
2014  bestI2=alignedI2;
2015  bestCorr=corr;
2016  shiftY=y;
2017  shiftX=x;
2018  }
2019  }
2020  I2=bestI2;
2021 
2022  return bestCorr;
2023 }
static double * y
double correlationIndex(const MultidimArray< T > &x, const MultidimArray< T > &y, const MultidimArray< int > *mask=NULL, MultidimArray< double > *Contributions=NULL)
doublereal * x
#define XX(v)
Definition: matrix1d.h:85
#define YY(v)
Definition: matrix1d.h:93
void translate(PDB *pdb_original, PDB *pdb_move, unsigned num_atoms, double x0, double y0, double z0)
Definition: lib_pwk.cpp:125

◆ boundMedianFilter()

template<typename T >
void boundMedianFilter ( MultidimArray< T > &  V,
const MultidimArray< char > &  mask,
int  n = 0 
)

Remove bad pixels.

A boundaries median filter is applied at those pixels given by the mask. The mask is set to zeros in the process of the tiltering. Keep a copy in case you further use it.

Definition at line 1309 of file filters.h.

1310 {
1311  bool badRemaining;
1312  T neighbours[125];
1313  T aux;
1314  int N = 0;
1315  int index;
1316 
1317  do
1318  {
1319  badRemaining=false;
1320 
1322  if (DIRECT_A3D_ELEM(mask, k, i, j) != 0)
1323  {
1324  N = 0;
1325  for (int kk=-2; kk<=2; kk++)
1326  {
1327  size_t kkk=k+kk;
1328  if (kkk<0 || kkk>=ZSIZE(V))
1329  continue;
1330  for (int ii=-2; ii<=2; ii++)
1331  {
1332  size_t iii=i+ii;
1333  if (iii<0 || iii>=YSIZE(V))
1334  continue;
1335  for (int jj=-2; jj<=2; jj++)
1336  {
1337  size_t jjj=j+jj;
1338  if (jjj<0 || jjj>=XSIZE(V))
1339  continue;
1340 
1341  if (DIRECT_A3D_ELEM(mask, kkk, iii, jjj) == 0)
1342  {
1343  index = N++;
1344  neighbours[index] = DIRECT_A3D_ELEM(V, kkk,iii,jjj);
1345  //insertion sort
1346  while (index > 0 && neighbours[index-1] > neighbours[index])
1347  {
1348  SWAP(neighbours[index-1], neighbours[index], aux);
1349  --index;
1350  }
1351  }
1352  }
1353  }
1354  if (N == 0)
1355  badRemaining = true;
1356  else
1357  {
1358  //std::sort(neighbours.begin(),neighbours.end());
1359  if (N % 2 == 0)
1360  DIRECT_A3D_ELEM(V, k, i, j) = (T)(0.5*(neighbours[N/2-1]+ neighbours[N/2]));
1361  else
1362  DIRECT_A3D_ELEM(V, k, i, j) = neighbours[N/2];
1363  DIRECT_A3D_ELEM(mask, k, i, j) = false;
1364  }
1365  }
1366  }
1367  }
1368  while (badRemaining);
1369 }
#define YSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
viol index
#define XSIZE(v)
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define j
#define SWAP(a, b, tmp)
Definition: xmipp_macros.h:428

◆ centerImage()

Matrix2D<double> centerImage ( MultidimArray< double > &  I,
CorrelationAux aux,
RotationalCorrelationAux aux2,
int  Niter = 10,
bool  limitShift = true 
)

Center an image both translationally and rotationally

Given an image, this function returns the image that has been centered rotationally and translationally. For doing so, it compares this image with its mirrored (X, Y, XY) versions. The image is aligned translationally and then rotationally Niter times.

Definition at line 3277 of file filters.cpp.

3279 {
3280  I.checkDimension(2);
3281 
3282  I.setXmippOrigin();
3283  double avg = I.computeAvg();
3284  I -= avg;
3285 
3289  MultidimArray<double> Iaux;
3290  Matrix2D<double> A;
3291  A.initIdentity(3);
3292  Iaux = I;
3293 
3294  MultidimArray<int> mask;
3295  mask.initZeros(I);
3296  BinaryCircularMask(mask, XSIZE(I) / 2);
3297 
3298  MultidimArray<double> lineY;
3299  MultidimArray<double> lineX;
3300  lineY.initZeros(YSIZE(I));
3301  STARTINGX(lineY) = STARTINGY(I);
3302  lineX.initZeros(XSIZE(I));
3303  STARTINGX(lineX) = STARTINGX(I);
3304 
3305  Polar_fftw_plans *plans = nullptr;
3306  Polar<std::complex<double> > polarFourierI;
3307  Polar<std::complex<double> > polarFourierIx;
3308  MultidimArray<double> rotationalCorr;
3309  Matrix2D<double> R;
3310  for (int i = 0; i < Niter; i++)
3311  {
3312  // Mask Iaux
3314  if (!A2D_ELEM(mask,i,j))
3315  A2D_ELEM(Iaux,i,j) = 0;
3316 
3317  // Center translationally
3318  Ix = Iaux;
3319  Ix.selfReverseX();
3320  Ix.setXmippOrigin();
3321  Iy = Iaux;
3322  Iy.selfReverseY();
3323  Iy.setXmippOrigin();
3324  Ixy = Ix;
3325  Ixy.selfReverseY();
3326  Ixy.setXmippOrigin();
3327 
3328  double meanShiftX = 0;
3329  double meanShiftY = 0;
3330  double shiftX;
3331  double shiftY;
3332  double Nx = 0;
3333  double Ny = 0;
3334  bestNonwrappingShift(Iaux, Ix, shiftX, shiftY, aux);
3335 #ifdef DEBUG
3336 
3337  ImageXmipp save;
3338  save()=Ix;
3339  save.write("PPPx.xmp");
3340  std::cout << "con Ix: " << shiftX << " " << shiftY << std::endl;
3341 #endif
3342 
3343  if (fabs(shiftX) < XSIZE(I) / 3 || !limitShift)
3344  {
3345  meanShiftX += shiftX;
3346  Nx++;
3347  }
3348  if (fabs(shiftY) < YSIZE(I) / 3 || !limitShift)
3349  {
3350  meanShiftY += shiftY;
3351  Ny++;
3352  }
3353  bestNonwrappingShift(Iaux, Iy, shiftX, shiftY, aux);
3354 #ifdef DEBUG
3355 
3356  save()=Iy;
3357  save.write("PPPy.xmp");
3358  std::cout << "con Iy: " << shiftX << " " << shiftY << std::endl;
3359 #endif
3360 
3361  if (fabs(shiftX) < XSIZE(I) / 3 || !limitShift)
3362  {
3363  meanShiftX += shiftX;
3364  Nx++;
3365  }
3366  if (fabs(shiftY) < YSIZE(I) / 3 || !limitShift)
3367  {
3368  meanShiftY += shiftY;
3369  Ny++;
3370  }
3371  bestNonwrappingShift(Iaux, Ixy, shiftX, shiftY, aux);
3372 #ifdef DEBUG
3373 
3374  save()=Ixy;
3375  save.write("PPPxy.xmp");
3376  std::cout << "con Ixy: " << shiftX << " " << shiftY << std::endl;
3377 #endif
3378 
3379  if (fabs(shiftX) < XSIZE(I) / 3 || !limitShift)
3380  {
3381  meanShiftX += shiftX;
3382  Nx++;
3383  }
3384  if (fabs(shiftY) < YSIZE(I) / 3 || !limitShift)
3385  {
3386  meanShiftY += shiftY;
3387  Ny++;
3388  }
3389  if (Nx > 0)
3390  meanShiftX /= Nx;
3391  if (Ny > 0)
3392  meanShiftY /= Ny;
3393 
3394  MAT_ELEM(A,0,2) += -meanShiftX / 2;
3395  MAT_ELEM(A,1,2) += -meanShiftY / 2;
3396  Iaux.initZeros();
3397  applyGeometry(xmipp_transformation::LINEAR, Iaux, I, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::WRAP);
3399  if (!A2D_ELEM(mask,i,j))
3400  A2D_ELEM(Iaux,i,j) = 0;
3401 
3402 #ifdef DEBUG
3403 
3404  std::cout << "Iter " << i << std::endl;
3405  std::cout << "shift=" << -meanShiftX << "," << -meanShiftY << std::endl;
3406  save()=I;
3407  save.write("PPP.xmp");
3408  save()=Iaux;
3409  save.write("PPPshift.xmp");
3410 #endif
3411 
3412  // Center rotationally
3413  Ix = Iaux;
3414  Ix.selfReverseX();
3415  Ix.setXmippOrigin();
3416 
3417  polarFourierTransform<true>(Iaux, polarFourierI, true, XSIZE(I) / 5,
3418  XSIZE(I) / 2, plans);
3419  rotationalCorr.resizeNoCopy(
3420  2 * polarFourierI.getSampleNoOuterRing() - 1);
3421  aux2.local_transformer.setReal(rotationalCorr);
3422 
3423  polarFourierTransform<true>(Ix, polarFourierIx, false,
3424  XSIZE(Ix) / 5, XSIZE(Ix) / 2, plans);
3425  double bestRot = best_rotation(polarFourierIx, polarFourierI, aux2);
3426  bestRot = realWRAP(bestRot,0,180);
3427  if (bestRot > 90)
3428  bestRot = bestRot - 180;
3429 
3430  rotation2DMatrix(bestRot / 2, R);
3431  A = R * A;
3432  Iaux.initZeros();
3433  applyGeometry(xmipp_transformation::LINEAR, Iaux, I, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::WRAP);
3435  if (!A2D_ELEM(mask,i,j))
3436  A2D_ELEM(Iaux,i,j) = 0;
3437 
3438 #ifdef DEBUG
3439 
3440  std::cout << "rot=" << -bestRot/2 << std::endl;
3441  save()=Iaux;
3442  save.write("PPProt.xmp");
3443 #endif
3444 
3445  // Remove horizontal/vertical ambiguity
3446  lineX.initZeros();
3447  lineY.initZeros();
3449  {
3450  double val = A2D_ELEM(Iaux,i,j);
3451  if (j == 0)
3452  lineY(i) = val;
3453  else if (lineY(i) < val)
3454  lineY(i) = val;
3455  if (i == 0)
3456  lineX(j) = val;
3457  else if (lineX(j) < val)
3458  lineX(j) = val;
3459  }
3460 
3461  double thX = lineX.computeMin()
3462  + 0.75 * (lineX.computeMax() - lineX.computeMin());
3463  double thY = lineY.computeMin()
3464  + 0.75 * (lineY.computeMax() - lineY.computeMin());
3465  int x0 = STARTINGX(lineX);
3466  while (lineX(x0) < thX)
3467  x0++;
3468  int y0 = STARTINGX(lineY);
3469  while (lineY(y0) < thY)
3470  y0++;
3471  int xF = FINISHINGX(lineX);
3472  while (lineX(xF) < thX)
3473  xF--;
3474  int yF = FINISHINGX(lineY);
3475  while (lineY(yF) < thY)
3476  yF--;
3477  if ((xF - x0) > (yF - y0))
3478  {
3479  rotation2DMatrix(-90., R);
3480  A = R * A;
3481  }
3482  applyGeometry(xmipp_transformation::LINEAR, Iaux, I, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::WRAP);
3483 #ifdef DEBUG
3484 
3485  lineX.write("PPPlineX.txt");
3486  lineY.write("PPPlineY.txt");
3487  std::cout << "dev X=" << xF-x0 << std::endl;
3488  std::cout << "dev Y=" << yF-y0 << std::endl;
3489  save()=Iaux;
3490  save.write("PPPhorver.xmp");
3491  std::cout << "Press any key\n";
3492  char c;
3493  std::cin >> c;
3494 #endif
3495 
3496  }
3497  applyGeometry(xmipp_transformation::BSPLINE3, Iaux, I, A, xmipp_transformation::IS_NOT_INV, xmipp_transformation::WRAP);
3498  I = Iaux;
3499  I += avg;
3500  delete plans;
3501  return A;
3502 }
#define YSIZE(v)
#define A2D_ELEM(v, i, j)
#define FINISHINGX(v)
doublereal * c
void resizeNoCopy(const MultidimArray< T1 > &v)
void BinaryCircularMask(MultidimArray< int > &mask, double radius, int mode, double x0, double y0, double z0)
Definition: mask.cpp:193
void applyGeometry(int SplineDegree, MultidimArray< std::complex< double > > &V2, const MultidimArray< std::complex< double > > &V1, const Matrix2D< double > &A, bool inv, bool wrap, std::complex< double > outside, MultidimArray< double > *BcoeffsPtr)
#define STARTINGX(v)
void bestNonwrappingShift(const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, CorrelationAux &aux)
Definition: filters.cpp:1895
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define STARTINGY(v)
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
double best_rotation(const Polar< std::complex< double > > &I1, const Polar< std::complex< double > > &I2, RotationalCorrelationAux &aux)
Definition: polar.cpp:212
T computeMin() const
#define y0
#define x0
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
#define XSIZE(v)
void write(const FileName &fn) const
#define xF
void rotation2DMatrix(T ang, Matrix2D< T > &result, bool homogeneous)
#define j
template void polarFourierTransform< true >(MultidimArray< double > const &, Polar< double > &, Polar< std::complex< double > > &, bool, int, int, Polar_fftw_plans *&, int)
Definition: polar.h:67
FourierTransformer local_transformer
Definition: polar.h:794
void initZeros()
Definition: matrix2d.h:626
#define realWRAP(x, x0, xF)
Definition: xmipp_macros.h:304
void initZeros(const MultidimArray< T1 > &op)
double computeAvg() const
#define yF
void initIdentity()
Definition: matrix2d.h:673
T computeMax() const

◆ centerImageRotationally()

void centerImageRotationally ( MultidimArray< double > &  I,
RotationalCorrelationAux aux 
)

Center an image rotationally

Given an image, this function returns the image that has been centered rotationally. For doing so, it compares this image with its mirrored (X) version.

Definition at line 3248 of file filters.cpp.

3250 {
3251  I.checkDimension(2);
3252 
3253  MultidimArray<double> Ix = I;
3254  Ix.selfReverseX();
3255  Ix.setXmippOrigin();
3256 
3257  Polar_fftw_plans *plans = nullptr;
3258  Polar<std::complex<double> > polarFourierI;
3259  Polar<std::complex<double> > polarFourierIx;
3260  polarFourierTransform<true>(Ix, polarFourierIx, false, XSIZE(Ix) / 5,
3261  XSIZE(Ix) / 2, plans);
3262  polarFourierTransform<true>(I, polarFourierI, true, XSIZE(I) / 5,
3263  XSIZE(I) / 2, plans);
3264 
3265  MultidimArray<double> rotationalCorr;
3266  rotationalCorr.resize(2 * polarFourierI.getSampleNoOuterRing() - 1);
3267  aux.local_transformer.setReal(rotationalCorr);
3268  double bestRot = best_rotation(polarFourierIx, polarFourierI, aux);
3269 
3270  MultidimArray<double> auxI = I;
3271  rotate(3, I, auxI, -bestRot / 2, xmipp_transformation::WRAP);
3272  //I.selfRotateBSpline(3,-bestRot/2,WRAP);
3273 }
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define rotate(a, i, j, k, l)
double best_rotation(const Polar< std::complex< double > > &I1, const Polar< std::complex< double > > &I2, RotationalCorrelationAux &aux)
Definition: polar.cpp:212
void setReal(MultidimArray< double > &img)
Definition: xmipp_fftw.cpp:129
#define XSIZE(v)
template void polarFourierTransform< true >(MultidimArray< double > const &, Polar< double > &, Polar< std::complex< double > > &, bool, int, int, Polar_fftw_plans *&, int)
Definition: polar.h:67
FourierTransformer local_transformer
Definition: polar.h:794

◆ centerImageTranslationally()

void centerImageTranslationally ( MultidimArray< double > &  I,
CorrelationAux aux 
)

Center an image translationally

Given an image, this function returns the image that has been centered translationally. For doing so, it compares this image with its mirrored (X, Y, XY) versions.

Definition at line 3212 of file filters.cpp.

3213 {
3214  I.checkDimension(2);
3215 
3216  MultidimArray<double> Ix = I;
3217  Ix.selfReverseX();
3218  Ix.setXmippOrigin();
3219  MultidimArray<double> Iy = I;
3220  Iy.selfReverseY();
3221  Iy.setXmippOrigin();
3222  MultidimArray<double> Ixy = Ix;
3223  Ixy.selfReverseY();
3224  Ixy.setXmippOrigin();
3225 
3226  double meanShiftX = 0;
3227  double meanShiftY = 0;
3228  double shiftX;
3229  double shiftY;
3230  bestNonwrappingShift(I, Ix, meanShiftX, meanShiftY, aux);
3231  bestNonwrappingShift(I, Iy, shiftX, shiftY, aux);
3232  meanShiftX += shiftX;
3233  meanShiftY += shiftY;
3234  bestNonwrappingShift(I, Ixy, shiftX, shiftY, aux);
3235  meanShiftX += shiftX;
3236  meanShiftY += shiftY;
3237  meanShiftX /= 3;
3238  meanShiftY /= 3;
3239 
3240  Matrix1D<double> shift(2);
3241  VECTOR_R2(shift, -meanShiftX, -meanShiftY);
3242  MultidimArray<double> aux2 = I;
3243  translate(3, I, aux2, shift);
3244  //I.selfTranslateBSpline(3,shift);
3245 }
#define VECTOR_R2(v, x, y)
Definition: matrix1d.h:112
void bestNonwrappingShift(const MultidimArray< double > &I1, const MultidimArray< double > &I2, double &shiftX, double &shiftY, CorrelationAux &aux)
Definition: filters.cpp:1895
void translate(PDB *pdb_original, PDB *pdb_move, unsigned num_atoms, double x0, double y0, double z0)
Definition: lib_pwk.cpp:125

◆ contrastEnhancement()

void contrastEnhancement ( Image< double > *  I)

Constrast enhancement

The minimum density value is brought to 0 and the maximum to 255.

Definition at line 327 of file filters.cpp.

328 {
329  (*I)().rangeAdjust(0, 255);
330 }

◆ correlation()

template<typename T >
double correlation ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
const MultidimArray< int > *  mask = nullptr,
int  l = 0,
int  m = 0,
int  q = 0 
)

Correlation nD

Definition at line 249 of file filters.h.

255 {
257 
258  double retval = 0; // returned value
259  int i;
260  int j;
261  int k;
262  int ip;
263  int jp;
264  int kp; // indexes
265  int Rows;
266  int Cols;
267  int Slices; // of the volumes
268 
269  // do the computation
270  Cols = XSIZE(x);
271  Rows = YSIZE(x);
272  Slices = ZSIZE(x);
273 
274  long N = 0;
275  for (k = 0; k < Slices; k++)
276  {
277  kp = k - q;
278  if (kp < 0 || kp >= Slices)
279  continue;
280  for (i = 0; i < Rows; i++)
281  {
282  ip = i - l;
283  if (ip < 0 || ip >= Rows)
284  continue;
285  for (j = 0; j < Cols; j++)
286  {
287  jp = j - m;
288 
289  if (jp >= 0 && jp < Cols)
290  {
291  if (mask != nullptr)
292  if (!DIRECT_A3D_ELEM((*mask), k, i, j))
293  continue;
294 
295  retval += DIRECT_A3D_ELEM(x, k, i, j) *
296  DIRECT_A3D_ELEM(y, kp, ip, jp);
297  ++N;
298  }
299  }
300  }
301  }
302 
303  return retval / N;
304 }
#define YSIZE(v)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define XSIZE(v)
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define SPEED_UP_temps
Definition: xmipp_macros.h:419
#define j
int m

◆ correlationIndex()

template<typename T >
double correlationIndex ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
const MultidimArray< int > *  mask = NULL,
MultidimArray< double > *  Contributions = NULL 
)

correlationIndex nD

Definition at line 3974 of file multidim_array.h.

3978 {
3980 
3981  double retval = 0, aux;
3982  double mean_x, mean_y;
3983  double stddev_x, stddev_y;
3984 
3985  long N = 0;
3986 
3987  if (mask == NULL)
3988  {
3989  x.computeAvgStdev(mean_x, stddev_x);
3990  y.computeAvgStdev(mean_y, stddev_y);
3991  }
3992  else
3993  {
3994  x.computeAvgStdev_within_binary_mask(*mask, mean_x,stddev_x);
3995  y.computeAvgStdev_within_binary_mask(*mask, mean_y,stddev_y);
3996  }
3997  if (ABS(stddev_x)<XMIPP_EQUAL_ACCURACY ||
3998  ABS(stddev_y)<XMIPP_EQUAL_ACCURACY)
3999  return 0;
4000 
4001  // If contributions are desired. Please, be careful interpreting individual
4002  // contributions to the covariance! One pixel value afect others.
4003  if (Contributions != NULL)
4004  {
4006  {
4007  if (mask != NULL)
4008  if (!A3D_ELEM(*mask,k, i, j))
4009  continue;
4010 
4011  aux = (A3D_ELEM(x, k, i, j) - mean_x) * (A3D_ELEM(y, k, i, j) -
4012  mean_y);
4013  A3D_ELEM(*Contributions, k, i, j) = aux;
4014  retval += aux;
4015  ++N;
4016  }
4017 
4018  FOR_ALL_ELEMENTS_IN_ARRAY3D(*Contributions)
4019  A3D_ELEM(*Contributions, k, i, j) /= ((stddev_x * stddev_y) * N);
4020  }
4021  else
4022  {
4023  if (mask==NULL && x.sameShape(y))
4024  {
4026  retval += DIRECT_MULTIDIM_ELEM(x, n)*DIRECT_MULTIDIM_ELEM(y, n);
4027  N=MULTIDIM_SIZE(x);
4028  retval-=N*mean_x*mean_y;
4029  }
4030  else
4031  {
4033  {
4034  if (mask != NULL)
4035  if (!A3D_ELEM(*mask,k, i, j))
4036  continue;
4037 
4038  retval += (A3D_ELEM(x, k, i, j) - mean_x) *
4039  (A3D_ELEM(y, k, i, j) - mean_y);
4040  ++N;
4041  }
4042  }
4043  }
4044 
4045  if (N != 0)
4046  return retval / ((stddev_x * stddev_y) * N);
4047  else
4048  return 0;
4049 }
#define MULTIDIM_SIZE(v)
void computeAvgStdev(U &avg, U &stddev) const
void computeAvgStdev_within_binary_mask(const MultidimArray< int > &mask, double &avg, double &stddev) const
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
#define XMIPP_EQUAL_ACCURACY
Definition: xmipp_macros.h:119
bool sameShape(const MultidimArrayBase &op) const
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ABS(x)
Definition: xmipp_macros.h:142
#define DIRECT_MULTIDIM_ELEM(v, n)
#define j
#define SPEED_UP_tempsInt
Definition: xmipp_macros.h:408
#define FOR_ALL_ELEMENTS_IN_COMMON_IN_ARRAY3D(V1, V2)
int * n

◆ correntropy()

template<typename T >
double correntropy ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
double  sigma 
)

Correntropy nD

Definition at line 381 of file filters.h.

383 {
384  double retval=0;
385  double K=-0.5/(sigma*sigma);
387  {
388  double diff=DIRECT_MULTIDIM_ELEM(x,n)-DIRECT_MULTIDIM_ELEM(y,n);
389  retval+=exp(K*diff*diff);
390  }
391  retval/=XSIZE(x)*YSIZE(x)*ZSIZE(x);
392  return retval;
393 }
#define YSIZE(v)
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
constexpr int K
int * n

◆ denoiseTVenergy()

double denoiseTVenergy ( double  mu,
const MultidimArray< double > &  X,
const MultidimArray< double > &  Y,
double  s,
double  q,
double  lambda,
double  sigmag,
double  g 
)

Compute energy.

  • energy function 0.5*|vst(X)-Y|^2 + mu*TV(X) = data_term + mu*TV

X=current image Y=sensed image mu=regularization weight (on TV norm)

Definition at line 3959 of file filters.cpp.

3967 {
3968  // parameter beta which role is to prevent division with zeros
3969  const double beta = 0.00001;
3970  const double beta2 = beta*beta;
3971 
3972  double m = 0;
3973  double tv = 0;
3974  const double K1 = ((3.0/8.0)*lambda*lambda + sigmag*sigmag - lambda*g) / (s*s);
3975  const double K2 = lambda * (q/(s*s));
3976  const double K3 = 2.0 / lambda;
3977  double Xij;
3978  double Yij;
3979  double dXx;
3980  double dXy;
3981  double d;
3982  double msqrt;
3983  int i1;
3984  int j1;
3985 
3987  {
3988  Xij = DIRECT_A2D_ELEM(X,i,j);
3989  Yij = DIRECT_A2D_ELEM(Y,i,j);
3990  i1 = i + 1;
3991  if (i1==YSIZE(X))
3992  i1 = 0;
3993  j1 = j + 1;
3994  if (j1==XSIZE(X))
3995  j1 = 0;
3996 
3997  dXx = DIRECT_A2D_ELEM(X,i,j1) - Xij;
3998  dXy = DIRECT_A2D_ELEM(X,i1,j) - Xij;
3999  tv += sqrt(dXx*dXx + dXy*dXy + beta2);
4000 
4001  d = K2*Xij + K1;
4002  msqrt = K3 * sqrt(std::max(0.0, d)) - Yij;
4003  m += msqrt*msqrt;
4004  }
4005  return 0.5*m + mu*tv;
4006 }
#define YSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
doublereal * g
double beta(const double a, const double b)
void sqrt(Image< double > &op)
#define DIRECT_A2D_ELEM(v, i, j)
#define i
doublereal * d
double * lambda
#define XSIZE(v)
void max(Image< double > &op1, const Image< double > &op2)
#define j
int m
int mu

◆ denoiseTVFilter()

void denoiseTVFilter ( MultidimArray< double > &  xnew,
int  maxIter 
)

Compute denoising.

Definition at line 4129 of file filters.cpp.

4130 {
4131  // parameters for denoising
4132  double lambda = 1.0; // Poisson scaling factor
4133  double sigmag = 5.8; // Gaussian component N(g,sigma^2)
4134  double g = 0.0;
4135 
4136  // *** Anscombe transformation of input image ***
4137  double q = 255.0;
4138 
4139  double xnewmin = xnew.computeMin();
4140  double xnewscale = 255.0 / (xnew.computeMax() - xnewmin);
4141 
4142  // apply generalized Anscombe VST tranformation
4143  double K1 = ((3.0/8.0)*lambda*lambda + sigmag*sigmag - lambda*g);
4145  {
4146  DIRECT_MULTIDIM_ELEM(xnew, n) = (DIRECT_MULTIDIM_ELEM(xnew, n) - xnewmin) * xnewscale;
4147  DIRECT_MULTIDIM_ELEM(xnew, n) = 2.0 / lambda * sqrt(std::max(0.0, lambda*DIRECT_MULTIDIM_ELEM(xnew, n) + K1));
4148  }
4149 
4150  double mx = xnew.computeMax();
4151 
4152  // xold = initial degraded image
4153  MultidimArray<double> xold = xnew;
4154  MultidimArray<double> grold = xnew;
4155  MultidimArray<double> grnew = xnew;
4156  MultidimArray<double> dold = xnew;
4158  {
4159  DIRECT_A2D_ELEM(xold,i,j) = DIRECT_A2D_ELEM(xnew,i,j) / mx;
4160  }
4161  MultidimArray<double> origInput = xold;
4162 
4163  // *** Spectral Projected Gradient (SPG) optimization ***
4164  // parameters of optimization
4165  double tol = 0;
4166  double theta;
4167  double thetamin = 0.001;
4168  double thetamax = 1000;
4169  double gamma = 0.0001;
4170  double sigma1 = 0.1;
4171  double sigma2 = 0.9;
4172  double mu = 0.03;
4173 
4174  // initial objective function value of xold
4175  double fold = denoiseTVenergy(mu, xold, origInput, mx, q, lambda, sigmag, g);
4176 
4177  // gradient of objective function
4178  denoiseTVgradient(mu, xold, origInput, mx, q, lambda, sigmag, g, grold);
4179 
4180  denoiseTVproj(xold, grold, 1.0, dold);
4181 
4182  double delta;
4183  double ksi;
4184  double fnew;
4185  double s_norm;
4186  double p;
4187  double s2;
4188  double xij;
4189  for (int kk=1; kk <= maxIter; kk++)
4190  {
4191  delta = 0;
4192 
4193  // make a step
4195  {
4196  DIRECT_A2D_ELEM(xnew,i,j) = DIRECT_A2D_ELEM(xold,i,j) + DIRECT_A2D_ELEM(dold,i,j);
4197  delta += DIRECT_A2D_ELEM(grold,i,j) * DIRECT_A2D_ELEM(dold,i,j);
4198  }
4199 
4200  // objective function of xnew
4201  fnew = denoiseTVenergy(mu, xnew, origInput, mx, q, lambda, sigmag, g);
4202 
4203  ksi = 1.0;
4204 
4205  while (fnew > fold + gamma*ksi*delta)
4206  {
4207  double ksitsl = -0.5 * (ksi*ksi) * delta / (fnew - fold - ksi*delta);
4208  if ((ksitsl >= sigma1) && (ksitsl <= sigma2*ksi))
4209  ksi = ksitsl;
4210  else
4211  ksi = ksi / 2.0;
4212 
4214  {
4215  DIRECT_A2D_ELEM(xnew,i,j) = DIRECT_A2D_ELEM(xold,i,j) + ksi*DIRECT_A2D_ELEM(dold,i,j);
4216  }
4217 
4218  // because we updated xnew, update also function value
4219  fnew = denoiseTVenergy(mu, xnew, origInput, mx, q, lambda, sigmag, g);
4220  }
4221 
4222  denoiseTVgradient(mu, xnew, origInput, mx, q, lambda, sigmag, g, grnew);
4223 
4224  s_norm = -100;
4225  p = 0;
4226  s2 = 0;
4228  {
4229  xij = (DIRECT_A2D_ELEM(xnew,i,j) - DIRECT_A2D_ELEM(xold,i,j));
4230  p += xij * (DIRECT_A2D_ELEM(grnew,i,j) - DIRECT_A2D_ELEM(grold,i,j));
4231  s2 += xij * xij;
4232  if (xij > s_norm) s_norm = xij;
4233  }
4234 
4235  if (s_norm < tol)
4236  break;
4237 
4238  if (p <= 0)
4239  theta = thetamax;
4240  else
4241  theta = std::min(thetamax, std::max(thetamin, s2/p));
4242 
4243  denoiseTVproj(xnew, grnew, theta, dold);
4244 
4246  {
4247  DIRECT_A2D_ELEM(xold,i,j) = DIRECT_A2D_ELEM(xnew,i,j);
4248  DIRECT_A2D_ELEM(grold,i,j) = DIRECT_A2D_ELEM(grnew,i,j);
4249  }
4250 
4251  // we already computed it, let's use it for next round
4252  fold = fnew;
4253  }
4254 }
void min(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
doublereal * g
void sqrt(Image< double > &op)
#define DIRECT_A2D_ELEM(v, i, j)
double * gamma
#define i
double theta
T computeMin() const
double * lambda
void max(Image< double > &op1, const Image< double > &op2)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void denoiseTVproj(const MultidimArray< double > &X, const MultidimArray< double > &Y, double theta, MultidimArray< double > &dold)
Definition: filters.cpp:4108
#define j
int mu
void denoiseTVgradient(double mu, const MultidimArray< double > &X, const MultidimArray< double > &Y, double s, double q, double lambda, double sigmag, double g, MultidimArray< double > &gradientI)
Definition: filters.cpp:4017
int * n
double denoiseTVenergy(double mu, const MultidimArray< double > &X, const MultidimArray< double > &Y, double s, double q, double lambda, double sigmag, double g)
Definition: filters.cpp:3959
double * xnew
T computeMax() const
double * delta

◆ denoiseTVgradient()

void denoiseTVgradient ( double  mu,
const MultidimArray< double > &  X,
const MultidimArray< double > &  Y,
double  s,
double  q,
double  lambda,
double  sigmag,
double  g,
MultidimArray< double > &  gradientI 
)

Compute gradient.

  • Jacobian of Energy_TV 0.5*|vst(X)-Y|^2 + mu*TV(X)

X=current image Y=sensed image mu=regularization weight (on TV norm)

Definition at line 4017 of file filters.cpp.

4027 {
4028  // parameter beta which role is to prevent division with zeros
4029  const double beta = 0.00001;
4030  const double beta2 = beta*beta;
4031 
4033  double K1 = ((3.0/8.0)*lambda*lambda + sigmag*sigmag - lambda*g) / (s*s);
4034  double K2 = lambda * (q/s*s);
4035  double K3 = (2.0 / (lambda*lambda)) * (q / (s*s)) * lambda;
4036  double Xij;
4037  double Yij;
4038  double dXx;
4039  double dXy;
4040  double dij;
4041  double d_left;
4042  double d_up;
4043  double X_left;
4044  double X_right;
4045  double X_up;
4046  double X_down;
4047  double dTV;
4048  double dE;
4049  int i1;
4050  int j1;
4051  int i_1;
4052  int j_1;
4053 
4055  {
4056  Xij = DIRECT_A2D_ELEM(X,i,j);
4057  i1 = i + 1;
4058  if (i1==YSIZE(X))
4059  i1 = 0;
4060  j1 = j + 1;
4061  if (j1==XSIZE(X))
4062  j1 = 0;
4063 
4064  dXx = DIRECT_A2D_ELEM(X,i,j1) - Xij;
4065  dXy = DIRECT_A2D_ELEM(X,i1,j) - Xij;
4066  DIRECT_A2D_ELEM(d,i,j) = 1.0 / sqrt(dXx*dXx + dXy*dXy + beta2);
4067  }
4068 
4070  {
4071  dij = DIRECT_A2D_ELEM(d,i,j);
4072  Xij = DIRECT_A2D_ELEM(X,i,j);
4073  Yij = DIRECT_A2D_ELEM(Y,i,j);
4074  i1 = i + 1;
4075  if (i1==YSIZE(d))
4076  i1 = 0;
4077  j1 = j + 1;
4078  if (j1==XSIZE(d))
4079  j1 = 0;
4080  i_1 = i - 1;
4081  if (i_1==-1)
4082  i_1 = YSIZE(d) - 1;
4083  j_1 = j - 1;
4084  if (j_1==-1)
4085  j_1 = XSIZE(d) - 1;
4086 
4087  d_left = DIRECT_A2D_ELEM(d,i,j_1);
4088  d_up = DIRECT_A2D_ELEM(d,i_1,j);
4089  X_left = DIRECT_A2D_ELEM(X,i,j_1);
4090  X_right = DIRECT_A2D_ELEM(X,i,j1);
4091  X_up = DIRECT_A2D_ELEM(X,i_1,j);
4092  X_down = DIRECT_A2D_ELEM(X,i1,j);
4093 
4094  dTV = Xij * (2.0*dij + d_left + d_up) - X_left*d_left - X_up*d_up - dij*(X_right + X_down);
4095 
4096  if (K2*Xij + K1 > 0)
4097  dE = K3 - (q / (s*s)) * Yij / sqrt(Xij * (q / (s*s)) * lambda + K1);
4098  else
4099  dE = 0;
4100 
4101  DIRECT_A2D_ELEM(gradientI,i,j) = dE + mu*dTV;
4102  }
4103 }
#define YSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
doublereal * g
double beta(const double a, const double b)
void sqrt(Image< double > &op)
#define DIRECT_A2D_ELEM(v, i, j)
#define i
doublereal * d
double * lambda
#define XSIZE(v)
#define j
int mu

◆ denoiseTVproj()

void denoiseTVproj ( const MultidimArray< double > &  X,
const MultidimArray< double > &  Y,
double  theta,
MultidimArray< double > &  dold 
)

Function which makes projections on feasible set.

Definition at line 4108 of file filters.cpp.

4112 {
4113  double div;
4115  {
4116  div = DIRECT_A2D_ELEM(X,i,j) - (DIRECT_A2D_ELEM(Y,i,j)*theta);
4117  if (div < 0)
4118  DIRECT_A2D_ELEM(dold,i,j) = 0 - DIRECT_A2D_ELEM(X,i,j);
4119  else if (div > 1)
4120  DIRECT_A2D_ELEM(dold,i,j) = 1 - DIRECT_A2D_ELEM(X,i,j);
4121  else
4122  DIRECT_A2D_ELEM(dold,i,j) = div - DIRECT_A2D_ELEM(X,i,j);
4123  }
4124 }
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY2D(m)
#define DIRECT_A2D_ELEM(v, i, j)
#define i
double theta
#define j

◆ detectBackground()

void detectBackground ( const MultidimArray< double > &  vol,
MultidimArray< double > &  mask,
double  alpha,
double &  final_mean 
)

Detect background

This function receives a Matrix3D vol, and try to find the background assuming that all the outside planes contain background, and apply interval confidence, were alpha is the probabity to fail. Mask is of the same size of vol, and is the solution, mask have value 1 if background else value 0

Definition at line 197 of file filters.cpp.

199 {
200 
201  // 2.1.-Background detection------------------------------------------
202  MultidimArray<double> bg; // We create the volumen with
203  bg.resizeNoCopy(vol); // -1:not visited 0:mol 1:background
204  bg.initConstant(-1); // -2:in the list
205 
206  // Ponemos las seis caras de esta variable como visitadas e inicializamos
207  // la cola de pixeles por visitar
208  std::queue<int> list_for_compute; // Lista del modo [x1,y1,z1,...,xi,yi,zi]
209  // que contiene los pixeles por procesar
210  std::vector<double> bg_values; // Vector con los valores del background
211  size_t xdim = XSIZE(bg);
212  size_t ydim = YSIZE(bg);
213  size_t zdim = ZSIZE(bg);
215  {
216  if (j == 0 || j == xdim - 1 || i == 0 || i == ydim - 1 || k == 0
217  || k == zdim - 1)
218  { // Visited coord
219  DIRECT_A3D_ELEM(bg,k,i,j) = 1;
220  // We introduce the values of the background
221  bg_values.push_back(DIRECT_A3D_ELEM(vol,k,i,j));
222 
223  }
224  if ((j == 1 || j == xdim - 2) && (i != 0) && (i != ydim - 1) && (k != 0)
225  && (k != zdim - 1))
226  { // Coord for compute for x
227  list_for_compute.push(j);
228  list_for_compute.push(i);
229  list_for_compute.push(k);
230  }
231  if ((i == 1 || i == ydim - 2) && (j > 1) && (j < xdim - 2) && (k != 0)
232  && (k != zdim - 1))
233  { // Coord for compute for y
234  list_for_compute.push(j);
235  list_for_compute.push(i);
236  list_for_compute.push(k);
237  }
238  if ((k == 1 || k == zdim - 2) && (j > 1) && (j < xdim - 2) && (i > 1)
239  && (i < ydim - 2))
240  { // Coord for compute for y
241  list_for_compute.push(j);
242  list_for_compute.push(i);
243  list_for_compute.push(k);
244  }
245  } // end of FOR_ALL_ELEMENTS
246 
247  // We work until the list_for_compute is empty
248  int n = 250; //each 250 pixels renew stats
249  int cont = 250; //We start here for compute stat for first time
250  double A=0; // A and B are numbers such the interval of confidence is [A,B]
251  double B=0; //
252  float z = icdf_gauss(1 - alpha / 2);
253  while (!list_for_compute.empty())
254  {
255 
256  //We compute stat when is needed
257  if (cont == n)
258  {
259  // Compute statistics
260  double avg=0;
261  double stddev=0;
262  computeAvgStddev(bg_values, avg, stddev);
263  final_mean = avg;
264  // Compute confidence interval
265  A = avg - (z * stddev);
266  B = avg + (z * stddev);
267  cont = 0;
268  } // end of if
269  // Now we start to take coords from the list_for_compute
270  int x_coord = list_for_compute.front();
271  list_for_compute.pop();
272  int y_coord = list_for_compute.front();
273  list_for_compute.pop();
274  int z_coord = list_for_compute.front();
275  list_for_compute.pop();
276  // Is visited
277  DIRECT_A3D_ELEM(bg,z_coord,y_coord,x_coord) = -2;
278  //We take the value
279  double value = DIRECT_A3D_ELEM(vol,z_coord,y_coord,x_coord);
280  // We see if is background or not
281  if (A <= value && value <= B)
282  {
283  // We now is background
284  DIRECT_A3D_ELEM(bg,z_coord,y_coord,x_coord) = 1;
285  // We introduce the values of the background
286  bg_values.push_back(value);
287  // We update the cont variable
288  cont++;
289 
290  // We add his neighbours in the list_for_compute
291  for (int xx = x_coord - 1; xx <= x_coord + 1; xx++)
292  for (int yy = y_coord - 1; yy <= y_coord + 1; yy++)
293  for (int zz = z_coord - 1; zz <= z_coord + 1; zz++)
294  //We see if it has been visited
295  if (DIRECT_A3D_ELEM(bg,zz,yy,xx) == -1) // not visited
296  {
297  // So we include it in the list
298  list_for_compute.push(xx);
299  list_for_compute.push(yy);
300  list_for_compute.push(zz);
301  // Is in the list
302  DIRECT_A3D_ELEM(bg,zz,yy,xx) = -2;
303  }
304  } // end of if
305  else
306  {
307  // Isn't background
308  DIRECT_A3D_ELEM(bg,z_coord,y_coord,x_coord) = 0;
309  }
310  } // end of while
311  // Now we change not visited for mol
313  if (DIRECT_A3D_ELEM(bg,k,i,j) == -1)
314  DIRECT_A3D_ELEM(bg,k,i,j) = 0;
315 
316  // End of 2.1-----------------------------------------------------------
317  // 2.2.-Matematical Morphology
318  MultidimArray<double> bg_mm; // We create the output volumen
319  bg_mm.initZeros(vol);
320  closing3D(bg, bg_mm, 26, 0, 1);
321  // Output
322  //typeCast(bg_mm,mask);
323  mask = bg_mm;
324 }
#define YSIZE(v)
double alpha
Smoothness parameter.
Definition: blobs.h:121
void resizeNoCopy(const MultidimArray< T1 > &v)
double icdf_gauss(double p)
void initConstant(T val)
#define FOR_ALL_DIRECT_ELEMENTS_IN_ARRAY3D(V)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void closing3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:422
void computeAvgStddev(const std::vector< T > &V, double &avg, double &stddev)
Definition: xmipp_funcs.h:358
#define XSIZE(v)
#define ZSIZE(v)
double z
#define DIRECT_A3D_ELEM(v, k, i, j)
#define j
void initZeros(const MultidimArray< T1 > &op)
int * n

◆ distanceTransform()

void distanceTransform ( const MultidimArray< int > &  in,
MultidimArray< int > &  out,
bool  wrap = false 
)

L1 distance transform

If wrap is set, the image borders are wrapped around. This is useful if the image coordinates represent angles

Definition at line 584 of file filters.cpp.

586 {
587  std::list<int> toExplore; /* A list of points to explore */
588 
589  in.checkDimension(2);
590 
591  out.resize(in);
592  out.initConstant(XSIZE(in) + YSIZE(in));
593 
594 #define CHECK_POINT_DIST(i,j,proposedDistance) \
595  { \
596  int ip=i; \
597  int jp=j; \
598  if (wrap) \
599  { \
600  ip=intWRAP(ip,STARTINGY(out),FINISHINGY(out));\
601  jp=intWRAP(jp,STARTINGX(out),FINISHINGX(out));\
602  } \
603  if (ip>=STARTINGY(out) && ip<=FINISHINGY(out) && \
604  jp>=STARTINGX(out) && jp<=FINISHINGX(out)) \
605  if (out(ip,jp)>proposedDistance) \
606  { \
607  out(ip,jp)=proposedDistance; \
608  toExplore.push_back(ip); \
609  toExplore.push_back(jp); \
610  toExplore.push_back(proposedDistance); \
611  } \
612  }
613 
614  // Look for all elements in the binary mask and set the corresponding
615  // distance to 0
617  if (in(i, j))
618  {
619  out(i, j) = 0;
620  CHECK_POINT_DIST(i-1, j, 1);
621  CHECK_POINT_DIST(i+1, j, 1);
622  CHECK_POINT_DIST(i, j-1, 1);
623  CHECK_POINT_DIST(i, j+1, 1);
624  }
625 
626  while (!toExplore.empty())
627  {
628  int i = toExplore.front();
629  toExplore.pop_front();
630  int j = toExplore.front();
631  toExplore.pop_front();
632  int proposedDistance = toExplore.front();
633  toExplore.pop_front();
634 
635  if (proposedDistance == out(i, j))
636  {
637  // If this is the current distance (i.e., it has not
638  // been supersceded by a later value
639  CHECK_POINT_DIST(i-1, j, proposedDistance+1);
640  CHECK_POINT_DIST(i+1, j, proposedDistance+1);
641  CHECK_POINT_DIST(i, j-1, proposedDistance+1);
642  CHECK_POINT_DIST(i, j+1, proposedDistance+1);
643  }
644  }
645 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
void initConstant(T val)
#define CHECK_POINT_DIST(i, j, proposedDistance)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
int in
#define XSIZE(v)
#define j

◆ EntropyOtsuSegmentation()

double EntropyOtsuSegmentation ( MultidimArray< double > &  V,
double  percentil = 0.05,
bool  binarizeVolume = true 
)

Segment an object using a combination of Otsu and Entropy method

The combination aims at minimizing Z(t)=-log10(sigma2B(t))/H(t) Minimizing the intraclass variance in Otsu is the same as maximizing sigma2B. H is the entropy of the two classes in the entropy method.

Then, the lowest percentil of Z is computed. The threshold applied to the volume is the first value in the curve Z(t) falling below this percentil.

The binarization threshold is returned

Definition at line 1145 of file filters.cpp.

1147 {
1148  //V.checkDimension(3);
1149 
1150  // Compute the probability density function
1151  Histogram1D hist;
1152  hist.clear();
1153  compute_hist(V, hist, 300);
1154  hist /= hist.sum();
1155 
1156  // Compute the cumulative 0th and 1st order moments
1157  double x;
1158  MultidimArray<double> mom0;
1159  MultidimArray<double> mom1;
1160  mom0.initZeros(XSIZE(hist));
1161  mom1.initZeros(XSIZE(hist));
1162  mom0(0) = hist(0);
1163  hist.index2val(0, x);
1164  mom1(0) = hist(0) * x;
1165  for (size_t i = 1; i < XSIZE(mom0); i++)
1166  {
1167  mom0(i) = mom0(i - 1) + hist(i);
1168  hist.index2val(i, x);
1169  mom1(i) = mom1(i - 1) + hist(i) * x;
1170  }
1171 
1172  // Entropy for black and white parts of the histogram
1173  const double epsilon = 1e-15;
1176  h1.initZeros(XSIZE(hist));
1177  h2.initZeros(XSIZE(hist));
1178  for (size_t i = 0; i < XSIZE(hist); i++)
1179  {
1180  // Entropy h1
1181  double w1 = mom0(i);
1182  if (w1 > epsilon)
1183  for (size_t ii = 0; ii <= i; ii++)
1184  if (hist(ii) > epsilon)
1185  {
1186  double aux = hist(ii) / w1;
1187  h1(i) -= aux * log10(aux);
1188  }
1189 
1190  // Entropy h2
1191  double w2 = 1 - mom0(i);
1192  if (w2 > epsilon)
1193  for (size_t ii = i + 1; ii < XSIZE(hist); ii++)
1194  if (hist(ii) > epsilon)
1195  {
1196  double aux = hist(ii) / w2;
1197  h2(i) -= aux * log10(aux);
1198  }
1199  }
1200 
1201  // Compute sigma2B and H
1202  MultidimArray<double> sigma2B;
1204  MultidimArray<double> HSigma2B;
1205  sigma2B.initZeros(XSIZE(hist) - 1);
1206  H.initZeros(XSIZE(hist) - 1);
1207  HSigma2B.initZeros(XSIZE(hist) - 1);
1208  for (size_t i = 0; i < XSIZE(hist) - 1; i++)
1209  {
1210  double w1 = mom0(i);
1211  double w2 = 1 - mom0(i);
1212  double mu1 = mom1(i);
1213  double mu2 = mom1(XSIZE(mom1) - 1) - mom1(i);
1214  sigma2B(i) = w1 * w2 * (mu1 - mu2) * (mu1 - mu2);
1215  H(i) = h1(i) + h2(i);
1216  HSigma2B(i) = -log10(sigma2B(i)) / H(i);
1217  // The logic behind this expression is
1218  // Otsu: max sigma2B -> max log10(sigma2B) -> min -log10(sigma2B)
1219  // Entropy: max H -> max H -> min 1/H
1220  }
1221 
1222  // Sort HSigma2B and take a given percentage of it
1223  MultidimArray<double> HSigma2Bsorted;
1224  HSigma2B.sort(HSigma2Bsorted);
1225  int iTh = ROUND(XSIZE(HSigma2B)*percentil);
1226  double threshold = HSigma2Bsorted(iTh);
1227 
1228  // Find the first value within HSigma2B falling below this threshold
1229  iTh = 0;
1230  while (A1D_ELEM(HSigma2B,iTh) >= threshold)
1231  iTh++;
1232  iTh--;
1233  if (iTh <= 0)
1234  x = threshold;
1235  else
1236  hist.index2val(iTh, x);
1237 
1238  if (binarizeVolume)
1239  V.binarize(x);
1240  return x;
1241 }
void clear()
Definition: histogram.cpp:40
void sort(MultidimArray< T > &result) const
#define A1D_ELEM(v, i)
doublereal * x
#define i
void threshold(double *phi, unsigned long nvox, double limit)
Definition: lib_vwk.cpp:524
void index2val(double i, double &v) const
Definition: histogram.h:295
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
void binarize(double val=0, double accuracy=XMIPP_EQUAL_ACCURACY, MultidimArray< int > *mask=NULL)
int mu1
#define XSIZE(v)
#define ROUND(x)
Definition: xmipp_macros.h:210
void log10(Image< double > &op)
void initZeros(const MultidimArray< T1 > &op)
double epsilon
double sum() const

◆ EntropySegmentation()

double EntropySegmentation ( MultidimArray< double > &  V)

Segment an object using Entropy method

Entropy method determines a threshold such that the entropy of the two classes is maximized

http://rsbweb.nih.gov/ij/plugins/download/Entropy_Threshold.java

Definition at line 1078 of file filters.cpp.

1079 {
1080  // V.checkDimension(3);
1081 
1082  // Compute the probability density function
1083  Histogram1D hist;
1084  hist.clear();
1085  compute_hist(V, hist, 200);
1086  hist /= hist.sum();
1087 
1088  // Compute the cumulative 0th and 1st order moments
1089  double x;
1090  MultidimArray<double> mom0;
1091  mom0.initZeros(XSIZE(hist));
1092  mom0(0) = hist(0);
1093  for (size_t i = 1; i < XSIZE(mom0); i++)
1094  mom0(i) = mom0(i - 1) + hist(i);
1095 
1096  // Entropy for black and white parts of the histogram
1097  const double epsilon = 1e-15;
1100  h1.initZeros(XSIZE(hist));
1101  h2.initZeros(XSIZE(hist));
1102  for (size_t i = 0; i < XSIZE(hist); i++)
1103  {
1104  // Entropy h1
1105  double w1 = mom0(i);
1106  if (w1 > epsilon)
1107  for (size_t ii = 0; ii <= i; ii++)
1108  if (hist(ii) > epsilon)
1109  {
1110  double aux = hist(ii) / w1;
1111  h1(i) -= aux * log10(aux);
1112  }
1113 
1114  // Entropy h2
1115  double w2 = 1 - mom0(i);
1116  if (w2 > epsilon)
1117  for (size_t ii = i + 1; ii < XSIZE(hist); ii++)
1118  if (hist(ii) > epsilon)
1119  {
1120  double aux = hist(ii) / w2;
1121  h2(i) -= aux * log10(aux);
1122  }
1123  }
1124 
1125  // Find histogram index with maximum entropy
1126  double Hmax = h1(0) + h2(0);
1127  size_t iHmax = 0;
1128  for (size_t i = 1; i < XSIZE(hist) - 1; i++)
1129  {
1130  double H = h1(i) + h2(i);
1131  if (H > Hmax)
1132  {
1133  Hmax = H;
1134  iHmax = i;
1135  }
1136  }
1137 
1138  hist.index2val(iHmax, x);
1139  V.binarize(x);
1140 
1141  return x;
1142 }
void clear()
Definition: histogram.cpp:40
doublereal * x
#define i
void index2val(double i, double &v) const
Definition: histogram.h:295
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
void binarize(double val=0, double accuracy=XMIPP_EQUAL_ACCURACY, MultidimArray< int > *mask=NULL)
#define XSIZE(v)
void log10(Image< double > &op)
void initZeros(const MultidimArray< T1 > &op)
double epsilon
double sum() const

◆ estimateGaussian2D()

void estimateGaussian2D ( const MultidimArray< double > &  I,
double &  a,
double &  b,
Matrix1D< double > &  mu,
Matrix2D< double > &  sigma,
bool  estimateMu = true,
int  iterations = 10 
)

Fit Gaussian spot to an image.

The fitted Gaussian is a*G(r,mu,sigma)+b where G(r,mu,sigma)=exp(-0.5 * (r-mu)^t sigma^-1 (r-mu))

You can choose if the center is estimated or it is assumed to be 0. You can choose the number of iterations for the estiamtion.

Definition at line 2390 of file filters.cpp.

2393 {
2394  I.checkDimension(2);
2395 
2397 
2398  // Estimate b
2399  Histogram1D hist;
2400  compute_hist(z, hist, 100);
2401  b = hist.percentil(5);
2402 
2403  // Iteratively estimate all parameters
2404  for (int n = 0; n < iterations; n++)
2405  {
2406  // Reestimate z
2408  z(i, j) = XMIPP_MAX(I(i,j)-b,0);
2409 
2410  // Sum of z
2411  double T = z.sum();
2412 
2413  // Estimate center
2414  mu.initZeros(2);
2415  if (estimateMu)
2416  {
2418  {
2419  double val = z(i, j);
2420  XX(mu) += val * j;
2421  YY(mu) += val * i;
2422  }
2423  mu /= T;
2424  }
2425 
2426  // Estimate sigma
2427  sigma.initZeros(2, 2);
2429  {
2430  double val = z(i, j);
2431  double j_mu = j - XX(mu);
2432  double i_mu = i - YY(mu);
2433  sigma(0, 0) += val * j_mu * j_mu;
2434  sigma(0, 1) += val * i_mu * j_mu;
2435  sigma(1, 1) += val * i_mu * i_mu;
2436  }
2437  sigma(1, 0) = sigma(0, 1);
2438  sigma /= T;
2439 
2440  // Estimate amplitude
2441  Matrix2D<double> sigmainv = sigma.inv();
2442  Matrix1D<double> r(2);
2443  double G2 = 0;
2444  a = 0;
2446  {
2447  XX(r) = j;
2448  YY(r) = i;
2449  double G = unnormalizedGaussian2D(r, mu, sigmainv);
2450  a += z(i, j) * G;
2451  G2 += G * G;
2452  }
2453  a /= G2;
2454 
2455  // Reestimate b
2457  {
2458  XX(r) = j;
2459  YY(r) = i;
2460  double G = unnormalizedGaussian2D(r, mu, sigmainv);
2461  z(i, j) = I(i, j) - a * G;
2462  }
2463  compute_hist(z, hist, 100);
2464  b = hist.percentil(5);
2465  }
2466 }
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
double percentil(double percent_mass)
Definition: histogram.cpp:160
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
doublereal * b
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
#define XX(v)
Definition: matrix1d.h:85
double unnormalizedGaussian2D(const Matrix1D< double > &r, const Matrix1D< double > &mu, const Matrix2D< double > &sigmainv)
Definition: filters.cpp:2379
double z
void initZeros()
Definition: matrix1d.h:592
#define j
#define YY(v)
Definition: matrix1d.h:93
void initZeros()
Definition: matrix2d.h:626
int * n
doublereal * a

◆ euclidianDistance()

template<typename T >
double euclidianDistance ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
const MultidimArray< int > *  mask = nullptr 
)

euclidian distance nD

Definition at line 672 of file filters.h.

675 {
677 
678  double retval = 0;
679  long n = 0;
680 
682  {
683  if (mask != nullptr)
684  if (!(*mask)(k, i, j))
685  continue;
686 
687  retval += (A3D_ELEM(x, k, i, j) - A3D_ELEM(y, k, i, j)) *
688  (A3D_ELEM(x, k, i, j) - A3D_ELEM(y, k, i, j));
689  n++;
690  }
691 
692  if (n != 0)
693  return sqrt(retval);
694  else
695  return 0;
696 }
void sqrt(Image< double > &op)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define A3D_ELEM(V, k, i, j)
#define SPEED_UP_temps
Definition: xmipp_macros.h:419
#define j
#define FOR_ALL_ELEMENTS_IN_COMMON_IN_ARRAY3D(V1, V2)
int * n

◆ fastCorrentropy()

template<typename T >
double fastCorrentropy ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
double  sigma,
const GaussianInterpolator G 
)

Fast Correntropy 1D

Definition at line 361 of file filters.h.

363 {
364  double retval=0;
365  double isigma=1.0/sigma;
367  retval+=G.getValue(isigma*(DIRECT_MULTIDIM_ELEM(x,n)-
368  DIRECT_MULTIDIM_ELEM(y,n)));
369  retval/=XSIZE(x);
370  return retval;
371 }
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
double getValue(double x) const
int * n

◆ fastMaskedCorrelation()

template<typename T >
double fastMaskedCorrelation ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
const MultidimArray< int > &  mask 
)

Correlation nD

Definition at line 310 of file filters.h.

313 {
314  double retval = 0; // returned value
315  long N = 0;
317  {
318  if (DIRECT_MULTIDIM_ELEM(mask,n))
319  {
320  retval += DIRECT_MULTIDIM_ELEM(x, n) * DIRECT_MULTIDIM_ELEM(y, n);
321  ++N;
322  }
323  }
324  return retval / N;
325 }
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
int * n

◆ fillBinaryObject()

void fillBinaryObject ( MultidimArray< double > &  I,
int  neighbourhood = 8 
)

Fill object

Everything that is not background is assumed to be object.

Definition at line 758 of file filters.cpp.

759 {
760  I.checkDimension(2);
761 
762  MultidimArray<double> label;
764  I(i, j) = 1 - I(i, j);
765  labelImage2D(I, label, neighbourhood);
766  double l0 = label(STARTINGY(I), STARTINGX(I));
768  if (label(i, j) == l0)
769  I(i, j) = 0;
770  else
771  I(i, j) = 1;
772 }
#define STARTINGX(v)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define STARTINGY(v)
#define j
int labelImage2D(const MultidimArray< double > &I, MultidimArray< double > &label, int neighbourhood)
Definition: filters.cpp:648

◆ fillTriangle()

void fillTriangle ( MultidimArray< double > &  img,
int *  tx,
int *  ty,
double  color 
)

Fill a triangle defined by three points

The points are supplied as a pointer to three integer positions. They can be negative

Definition at line 3012 of file filters.cpp.

3013 {
3014  img.checkDimension(2);
3015 
3016  /*
3017  * Order in y values
3018  */
3019  int y1 = 0;
3020  while (!y1)
3021  {
3022  y1 = 1;
3023  for (int y2 = 0; y2 < 2; y2++)
3024  {
3025  if (ty[y2] > ty[y2 + 1]
3026  || (ty[y2] == ty[y2 + 1] && tx[y2] < tx[y2 + 1]))
3027  {
3028  int x1 = ty[y2];
3029  ty[y2] = ty[y2 + 1];
3030  ty[y2 + 1] = x1;
3031  x1 = tx[y2];
3032  tx[y2] = tx[y2 + 1];
3033  tx[y2 + 1] = x1;
3034  y1 = 0;
3035  }
3036  }
3037  }
3038 
3039  int dx1 = tx[1] - tx[0];
3040  int dx2 = tx[2] - tx[0];
3041  int dy1 = ty[1] - ty[0];
3042  int dy2 = ty[2] - ty[0];
3043 
3044  int sx1 = SGN0(dx1);
3045  int sx2 = SGN0(dx2);
3046  int sy1 = SGN0(dy1);
3047 
3048  int ix1 = ABS(dx1);
3049  int ix2 = ABS(dx2);
3050  int iy1 = ABS(dy1);
3051  int iy2 = ABS(dy2);
3052 
3053  int inc1 = XMIPP_MAX(ix1, iy1);
3054  int inc2 = XMIPP_MAX(ix2, iy2);
3055 
3056  int x1;
3057  int x2;
3058  int y2;
3059  int xl;
3060  int xr;
3061  x1 = x2 = y1 = y2 = 0;
3062  xl = xr = tx[0];
3063  int y = ty[0];
3064 
3065  while (y != ty[1])
3066  {
3067  int doit1 = 0;
3068  int doit2 = 0;
3069 
3070  while (!doit1)
3071  { /* Wait until y changes */
3072  x1 += ix1;
3073  y1 += iy1;
3074  if (x1 > inc1)
3075  {
3076  x1 -= inc1;
3077  xl += sx1;
3078  }
3079  if (y1 > inc1)
3080  {
3081  y1 -= inc1;
3082  y += sy1;
3083  doit1 = 1;
3084  }
3085  }
3086 
3087  while (!doit2)
3088  { /* Wait until y changes */
3089  x2 += ix2;
3090  y2 += iy2;
3091  if (x2 > inc2)
3092  {
3093  x2 -= inc2;
3094  xr += sx2;
3095  }
3096  if (y2 > inc2)
3097  {
3098  y2 -= inc2;
3099  doit2 = 1;
3100  }
3101  }
3102 
3103  for (int myx = xl; myx <= xr; myx++)
3104  img(y, myx) = color;
3105  }
3106 
3107  dx1 = tx[2] - tx[1];
3108  dy1 = ty[2] - ty[1];
3109 
3110  sx1 = SGN0(dx1);
3111  sy1 = SGN0(dy1);
3112 
3113  ix1 = ABS(dx1);
3114  iy1 = ABS(dy1);
3115 
3116  inc1 = XMIPP_MAX(ix1, iy1);
3117  xl = tx[1];
3118  x1 = 0;
3119 
3120  while (y != ty[2])
3121  {
3122  int doit1 = 0;
3123  int doit2 = 0;
3124 
3125  while (!doit1)
3126  { /* Wait until y changes */
3127  x1 += ix1;
3128  y1 += iy1;
3129  if (x1 > inc1)
3130  {
3131  x1 -= inc1;
3132  xl += sx1;
3133  }
3134  if (y1 > inc1)
3135  {
3136  y1 -= inc1;
3137  y += sy1;
3138  doit1 = 1;
3139  }
3140  }
3141 
3142  while (!doit2)
3143  { /* Wait until y changes */
3144  x2 += ix2;
3145  y2 += iy2;
3146  if (x2 > inc2)
3147  {
3148  x2 -= inc2;
3149  xr += sx2;
3150  }
3151  if (y2 > inc2)
3152  {
3153  y2 -= inc2;
3154  doit2 = 1;
3155  }
3156  }
3157 
3158  for (int myx = xl; myx <= xr; myx++)
3159  img(y, myx) = color;
3160  }
3161 }
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
doublereal * xl
#define SGN0(x)
Definition: xmipp_macros.h:169
static double * y
#define ABS(x)
Definition: xmipp_macros.h:142

◆ forcePositive()

void forcePositive ( MultidimArray< double > &  V)

Force positive.

A median filter is applied at those negative values. Positive values are untouched.

Force positive -----------------------------------------------------—

Definition at line 3506 of file filters.cpp.

3507 {
3508  MultidimArray<char> mask(ZSIZE(V), YSIZE(V), XSIZE(V));
3510  {
3511  double x = DIRECT_MULTIDIM_ELEM(V, n);
3512  DIRECT_MULTIDIM_ELEM(mask, n) = (x <= 0);
3513  }
3514  boundMedianFilter(V, mask);
3515 }
#define YSIZE(v)
doublereal * x
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
void boundMedianFilter(MultidimArray< T > &V, const MultidimArray< char > &mask, int n=0)
Definition: filters.h:1309
int * n

◆ fourierBesselDecomposition()

void fourierBesselDecomposition ( const MultidimArray< double > &  img_in,
double  r2,
int  k1,
int  k2 
)

Fourier-Bessel decomposition

The Fourier-Bessel decomposition of those pixels in img_in whose radius is between r1 and r2 is computed. r1 and r2 are supposed to fit in the image shape, and the image logical origin is used for the decomposition. k1 and k2 determines the harmonic coefficients to be computed.

Definition at line 2469 of file filters.cpp.

2471 {
2472  img_in.checkDimension(2);
2473 
2474  for (int k = k1; k <= k2; k++)
2475  {
2476  int k_1 = k - 1;
2477 
2478  // Compute h and a,b coefficients
2479  double h = 0;
2480  double my5 = 0;
2481  if (k_1 != 0)
2482  {
2483  double my = 1 + PI * r2 / 2 / k_1;
2484  double my4 = my * k_1;
2485  double ntot = 4 * my4;
2486  h = 2 * PI / ntot;
2487  }
2488  else
2489  {
2490  double my = 1 + PI * r2 / 2;
2491  double my4 = my;
2492  double ntot = 4 * my4;
2493  h = 2 * PI / ntot;
2494  }
2495 
2496  MultidimArray<double> sine(CEIL(my5));
2498  sine(i) = sin((i + 1) * h);
2499 
2500  }
2501 }
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
int ntot
#define CEIL(x)
Definition: xmipp_macros.h:225
#define FOR_ALL_ELEMENTS_IN_ARRAY1D(v)
float r2
#define PI
Definition: tools.h:43

◆ giniCoeff()

double giniCoeff ( MultidimArray< double > &  I,
int  varKernelSize = 50 
)

Returns the Gini coefficient of an image. This is related to the Entropy. It also applies a variance filter to the input Image

Definition at line 972 of file filters.cpp.

973 {
974  MultidimArray<double> im = I;
975 
976  // std::cout << " - Starting fft filtering " << std::endl;
977 
978  FourierFilter filter;
979  filter.FilterShape = REALGAUSSIAN;
980  filter.FilterBand = LOWPASS;
981  filter.w1 = 4;
982  filter.applyMaskSpace(im);
983 
984  // Image<double> imG(im);
985  // imG.write("I_Gauss.mrc");
986 
987  // std::cout << " - Calling varianceFilter() " << std::endl;
988  varianceFilter(I, varKernelSize, true);
989  im = I;
990 
991  // std::cout << " - Starting 2nd fft filtering " << std::endl;
992  filter.w1 = varKernelSize/8;
993  filter.applyMaskSpace(I);
994 
995  // Image<double> imGV(im);
996  // imGV.write("I_Gauss_Var.mrc");
997 
998  im -= im.computeMin();
999  im /= im.computeMax();
1000 
1001  // Image<double> imGVN(im);
1002  // imGVN.write("I_Gauss_Var_Norm.mrc");
1003 
1004  // std::cout << " - Starting histogram analysis " << std::endl;
1005  Histogram1D hist;
1006  hist.clear();
1007  compute_hist(im, hist, 256);
1008 
1009  // std::cout << " - Computing Gini coeff " << std::endl;
1010  MultidimArray<double> sortedList=hist;
1011  hist.sort(sortedList);
1012  double height=0;
1013  double area=0;
1014  for (int i=0; i<XSIZE(sortedList); i++)
1015  {
1016  height += DIRECT_MULTIDIM_ELEM(sortedList,i);
1017  area += height - DIRECT_MULTIDIM_ELEM(sortedList,i)/2.0;
1018  }
1019 
1020  double fair_area = height*XSIZE(hist)/2.0;
1021 
1022  double giniValue = (fair_area-area)/fair_area;
1023 
1024  return giniValue;
1025 }
void clear()
Definition: histogram.cpp:40
void sort(MultidimArray< T > &result) const
#define i
void varianceFilter(MultidimArray< double > &I, int kernelSize, bool relative)
Definition: filters.cpp:775
T computeMin() const
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
#define XSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
#define REALGAUSSIAN
#define LOWPASS
void applyMaskSpace(MultidimArray< double > &v)
T computeMax() const

◆ inertiaMoments()

void inertiaMoments ( const MultidimArray< double > &  img,
const MultidimArray< int > *  mask,
Matrix1D< double > &  v_out,
Matrix2D< double > &  u 
)

Inertia moments

They are measured with respect to the center of the image, and not with respect to the center of mass. For an image there are only two inertia moments. v_out contains the inertia moments while the columns of u contain the directions of the principal axes.

Definition at line 2970 of file filters.cpp.

2973 {
2974  img.checkDimension(2);
2975 
2976  // Prepare some variables
2977  double m_11 = 0;
2978  double m_02 = 0;
2979  double m_20 = 0;
2980  double normalize_x = 2.0 / XSIZE(img);
2981  double normalize_y = 2.0 / YSIZE(img);
2982 
2983  // Compute low-level moments
2985  {
2986  if (mask != nullptr)
2987  if (!(*mask)(i, j))
2988  continue;
2989  double val = img(i, j);
2990  double dx = j * normalize_x;
2991  double dy = i * normalize_y;
2992  double dx2 = dx * dx;
2993  double dy2 = dy * dy;
2994  m_11 += val * dx * dy;
2995  m_02 += val * dy2;
2996  m_20 += val * dx2;
2997  }
2998 
2999  // Compute the eigen values of the inertia matrix
3000  // [m_02 m_11
3001  // m_11 m_20]
3002  Matrix2D<double> A(2, 2);
3003  A(0, 0) = m_02;
3004  A(0, 1) = A(1, 0) = m_11;
3005  A(1, 1) = m_20;
3006  Matrix2D<double> v;
3007  svdcmp(A, u, v_out, v);
3008  v_out = v_out.sort();
3009 }
#define YSIZE(v)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define XSIZE(v)
double dx
void svdcmp(const Matrix2D< T > &a, Matrix2D< double > &u, Matrix1D< double > &w, Matrix2D< double > &v)
Definition: matrix2d.cpp:125
#define j
Matrix1D< T > sort() const
Definition: matrix1d.cpp:850

◆ keepBiggestComponent()

void keepBiggestComponent ( MultidimArray< double > &  I,
double  percentage = 0,
int  neighbourhood = 8 
)

Keep the biggest connected component

If the biggest component does not cover the percentage required (by default, 0), more big components are taken until this is accomplished.

Definition at line 713 of file filters.cpp.

715 {
716  MultidimArray<double> label;
717  int imax;
718  if (ZSIZE(I)==1)
719  imax=labelImage2D(I, label, neighbourhood);
720  else
721  imax=labelImage3D(I, label);
722  MultidimArray<int> nlabel(imax + 1);
724  {
725  int l=(int)DIRECT_MULTIDIM_ELEM(label,n);
726  if (l>0)
727  A1D_ELEM(nlabel,l)++;
728  }
729 
730  MultidimArray <int> best;
731  nlabel.indexSort(best);
732  best -= 1;
733  int nbest = XSIZE(best) - 1;
734  double total = nlabel.sum();
735  double explained = nlabel(best(nbest));
736  while (explained < percentage * total)
737  {
738  nbest--;
739  explained += nlabel(best(nbest));
740  }
741 
743  {
744  int l=(int)DIRECT_MULTIDIM_ELEM(label,n);
745  bool among_the_best = false;
746  for (int k = nbest; k < imax + 1; k++)
747  if (l == A1D_ELEM(best,k))
748  {
749  among_the_best = true;
750  break;
751  }
752  if (!among_the_best)
753  DIRECT_MULTIDIM_ELEM(I,n)=0;
754  }
755 }
#define A1D_ELEM(v, i)
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
int labelImage2D(const MultidimArray< double > &I, MultidimArray< double > &label, int neighbourhood)
Definition: filters.cpp:648
int labelImage3D(const MultidimArray< double > &V, MultidimArray< double > &label)
Definition: filters.cpp:669
int * n
void indexSort(MultidimArray< int > &indx) const

◆ labelImage2D()

int labelImage2D ( const MultidimArray< double > &  I,
MultidimArray< double > &  label,
int  neighbourhood = 8 
)

Label a binary image

This function receives a binary volume and labels all its connected components. The background is labeled as 0, and the components as 1, 2, 3 ...

Definition at line 648 of file filters.cpp.

650 {
651  I.checkDimension(2);
652 
653  label = I;
654  int colour = 32000;
656  {
657  if (label(i, j) != 1)
658  continue;
659  regionGrowing2D(label, label, i, j, 0, colour, false, neighbourhood);
660  colour++;
661  }
663  if (label(i, j) != 0)
664  label(i, j) = label(i, j) - 31999;
665  return colour - 32000;
666 }
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
void regionGrowing2D(const MultidimArray< double > &I_in, MultidimArray< double > &I_out, int i, int j, float stop_colour, float filling_colour, bool less, int neighbourhood)
Definition: filters.cpp:340
#define j

◆ labelImage3D()

int labelImage3D ( const MultidimArray< double > &  V,
MultidimArray< double > &  label 
)

Label a binary volume

This function receives a binary image and labels all its connected components. The background is labeled as 0, and the components as 1, 2, 3 ...

Definition at line 669 of file filters.cpp.

670 {
671  V.checkDimension(3);
672 
673  label = V;
674  int colour = 32000;
676  {
677  if (label(k, i, j) != 1)
678  continue;
679  regionGrowing3D(label, label, k, i, j, 0, colour, false);
680  colour++;
681  }
683  if (A3D_ELEM(label,k, i, j) != 0)
684  A3D_ELEM(label,k, i, j) = A3D_ELEM(label,k, i, j) - 31999;
685  return colour - 32000;
686 }
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
#define j
void regionGrowing3D(const MultidimArray< double > &V_in, MultidimArray< double > &V_out, int k, int i, int j, float stop_colour, float filling_colour, bool less)
Definition: filters.cpp:412

◆ localThresholding()

void localThresholding ( MultidimArray< double > &  img,
double  C,
double  dimLocal,
MultidimArray< int > &  result,
MultidimArray< int > *  mask = nullptr 
)

Local thresholding

This function implements the local thresholding as described in http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm A mask can be supplied to limit the image area.

The procedure employed is the following:

  • Convolving the image with the statistical operator, i.e. the mean or median (the size of the convolution kernel is dimLocal)
  • Subtracting the original from the convolved image.
  • Thresholding the difference image with C.
  • Inverting the thresholded image.

Definition at line 3164 of file filters.cpp.

3166 {
3167 
3168  // Convolve the input image with the kernel
3169  MultidimArray<double> convolved;
3170  convolved.initZeros(img);
3171  FOR_ALL_ELEMENTS_IN_ARRAY2D(convolved)
3172  {
3173  if (mask != nullptr)
3174  if (!(*mask)(i, j))
3175  continue;
3176  int ii0 = XMIPP_MAX(STARTINGY(convolved), FLOOR(i - dimLocal));
3177  int jj0 = XMIPP_MAX(STARTINGX(convolved), FLOOR(j - dimLocal));
3178  int iiF = XMIPP_MIN(FINISHINGY(convolved), CEIL(i + dimLocal));
3179  int jjF = XMIPP_MIN(FINISHINGX(convolved), CEIL(j + dimLocal));
3180  double N = 0;
3181  for (int ii = ii0; ii <= iiF; ii++)
3182  for (int jj = jj0; jj <= jjF; jj++)
3183  {
3184  if (mask == nullptr)
3185  {
3186  convolved(i, j) += img(ii, jj);
3187  ++N;
3188  }
3189  else if ((*mask)(i, j))
3190  {
3191  convolved(i, j) += img(ii, jj);
3192  ++N;
3193  }
3194  }
3195  if (N != 0)
3196  convolved(i, j) /= N;
3197  }
3198 
3199  // Subtract the original from the convolved image and threshold
3200  result.initZeros(img);
3201  FOR_ALL_ELEMENTS_IN_ARRAY2D(convolved)
3202  {
3203  if (mask != nullptr)
3204  if (!(*mask)(i, j))
3205  continue;
3206  if (img(i, j) - convolved(i, j) > C)
3207  result(i, j) = 1;
3208  }
3209 }
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
#define FINISHINGX(v)
#define STARTINGX(v)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define STARTINGY(v)
#define FLOOR(x)
Definition: xmipp_macros.h:240
#define CEIL(x)
Definition: xmipp_macros.h:225
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
#define FINISHINGY(v)
void initZeros(const MultidimArray< T1 > &op)

◆ logFilter()

template<typename T >
void logFilter ( MultidimArray< T > &  V,
double  a,
double  b,
double  c 
)

Compute logarithm.

apply transformation a+b*ln(x+c). i.e: 4.431-0.4018*LN(P1+336.6)

Definition at line 1411 of file filters.h.

1412 {
1413 
1415  {
1416  double x = DIRECT_MULTIDIM_ELEM(V, n);
1417  //this casting is kind of risky
1418  DIRECT_MULTIDIM_ELEM(V, n) = (T)(a-b*log(x+c));
1419  }
1420 }
doublereal * c
doublereal * x
doublereal * b
void log(Image< double > &op)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
int * n
doublereal * a

◆ medianFilter3x3()

template<typename T >
void medianFilter3x3 ( MultidimArray< T > &  m,
MultidimArray< T > &  out 
)

Median_filter with a 3x3 selfWindow

Definition at line 1088 of file filters.h.

1089 {
1090  int backup_startingx = STARTINGX(m);
1091  int backup_startingy = STARTINGY(m);
1092 
1093  STARTINGX(m) = STARTINGY(m) = 0;
1095  MultidimArray< T > v2(3);
1096  MultidimArray< T > v3(3);
1097  MultidimArray< T > v4(3);
1098  MultidimArray< T > v(6);
1099 
1100  // Set the output matrix size
1101  out.initZeros(m);
1102 
1103  // Set the initial and final matrix indices to explore
1104  int initialY = 1;
1105  int initialX = 1;
1106  int finalY = YSIZE(m) - 2;
1107  int finalX = XSIZE(m) - 2;
1108 
1109  // For every row
1110  for (int i = initialY; i <= finalY; i++)
1111  {
1112  // For every pair of pixels (mean is computed obtaining
1113  // two means at the same time using an efficient method)
1114  for (int j = initialX; j <= finalX; j += 2)
1115  {
1116  // If we are in the border case
1117  if (j == 1)
1118  {
1119  // Order the first and second vectors of 3 elements
1120  sort(DIRECT_A2D_ELEM(m, i - 1, j - 1), DIRECT_A2D_ELEM(m, i, j - 1),
1121  DIRECT_A2D_ELEM(m, i + 1, j - 1), v1);
1122  sort(DIRECT_A2D_ELEM(m, i - 1, j), DIRECT_A2D_ELEM(m, i, j),
1123  DIRECT_A2D_ELEM(m, i + 1, j), v2);
1124  }
1125  else
1126  {
1127  // Simply take ordered vectors from previous
1128  v1 = v3;
1129  v2 = v4;
1130  }
1131 
1132  // As we are computing 2 medians at the same time, if the matrix has
1133  // an odd number of columns, the last column isn't calculated. It is
1134  // done here
1135  if (j == finalX)
1136  {
1137  v1 = v3;
1138  v2 = v4;
1139  sort(DIRECT_A2D_ELEM(m, i - 1, j + 1), DIRECT_A2D_ELEM(m, i, j + 1),
1140  DIRECT_A2D_ELEM(m, i + 1, j + 1), v3);
1141  fastMergeSort(v2, v3, v);
1142  median(v1, v, DIRECT_A2D_ELEM(out,i, j));
1143  }
1144  else
1145  {
1146  // Order the third and fourth vectors of 3 elements
1147  sort(DIRECT_A2D_ELEM(m, i - 1, j + 1), DIRECT_A2D_ELEM(m, i, j + 1),
1148  DIRECT_A2D_ELEM(m, i + 1, j + 1), v3);
1149  sort(DIRECT_A2D_ELEM(m, i - 1, j + 2), DIRECT_A2D_ELEM(m, i, j + 2),
1150  DIRECT_A2D_ELEM(m, i + 1, j + 2), v4);
1151 
1152  // Merge sort the second and third vectors
1153  fastMergeSort(v2, v3, v);
1154 
1155  // Find the first median and assign it to the output
1156  median(v1, v, DIRECT_A2D_ELEM(out, i, j));
1157 
1158  // Find the second median and assign it to the output
1159  median(v4, v, DIRECT_A2D_ELEM(out, i, j + 1));
1160  }
1161  }
1162  }
1163 
1164  STARTINGX(m) = STARTINGX(out) = backup_startingx;
1165  STARTINGY(m) = STARTINGY(out) = backup_startingy;
1166 }
#define YSIZE(v)
#define DIRECT_A2D_ELEM(v, i, j)
void sort(T a, T b, T c, MultidimArray< T > &v)
Definition: filters.h:798
#define STARTINGX(v)
#define i
void median(MultidimArray< T > &x, MultidimArray< T > &y, T &m)
Definition: filters.h:1055
#define STARTINGY(v)
double v1
#define XSIZE(v)
#define j
void fastMergeSort(MultidimArray< T > &x, MultidimArray< T > &y, MultidimArray< T > &v)
Definition: filters.h:867
void initZeros(const MultidimArray< T1 > &op)

◆ mutualInformation()

template<typename T >
double mutualInformation ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
int  nx = 0,
int  ny = 0,
const MultidimArray< int > *  mask = nullptr 
)

mutual information nD

Return the mutual information: MI = sum [ P(x,y)*log2{P(x,y)/(P(x)*P(y))} ] in the common positions. P(x), P(y) are 1D-histograms of the values of matrix x and y. P(x,y) is the 2D-histogram, i.e. the count of times that a certain combination of values in matrices x and y has occurred. The sum runs over all histogram bins.

The histograms are calculated using the number of bins nx and ny. If no values (or zeros) are given, a Gaussian distribution of the values in the matrices is assumed, and the number of bins is calculated as: log2(n)+1. (according to: Tourassi et al. (2001) Med. Phys. 28 pp. 2394-2402.)

Definition at line 4291 of file filters.cpp.

4296 {
4298 
4299  long n = 0;
4300  Histogram1D histx;
4301  Histogram1D histy;
4302  Histogram2D histxy;
4303  MultidimArray< T > aux_x;
4304  MultidimArray< T > aux_y;
4308  int xdim;
4309  int ydim;
4310  int zdim;
4311  double retval = 0.0;
4312 
4313  xdim=XSIZE(x);
4314  ydim=YSIZE(x);
4315  zdim=ZSIZE(x);
4316  aux_x.resize(xdim * ydim * zdim);
4317  xdim=XSIZE(y);
4318  ydim=YSIZE(y);
4319  zdim=ZSIZE(y);
4320  aux_y.resize(xdim * ydim * zdim);
4321 
4323  {
4324  if (mask != nullptr)
4325  if (!(*mask)(k, i, j))
4326  continue;
4327 
4328  aux_x(n) = A3D_ELEM(x, k, i, j);
4329  aux_y(n) = A3D_ELEM(y, k, i, j);
4330  n++;
4331  }
4332 
4333  aux_x.resize(n);
4334  aux_y.resize(n);
4335 
4336  if (n != 0)
4337  {
4338  if (nx == 0)
4339  //Assume Gaussian distribution
4340  nx = (int)((log((double) n) / LOG2) + 1);
4341 
4342  if (ny == 0)
4343  //Assume Gaussian distribution
4344  ny = (int)((log((double) n) / LOG2) + 1);
4345 
4346  compute_hist(aux_x, histx, nx);
4347  compute_hist(aux_y, histy, ny);
4348  compute_hist(aux_x, aux_y, histxy, nx, ny);
4349 
4350  mx = histx;
4351  my = histy;
4352  mxy = histxy;
4353  for (int i = 0; i < nx; i++)
4354  {
4355  double histxi = (histx(i)) / n;
4356  for (int j = 0; j < ny; j++)
4357  {
4358  double histyj = (histy(j)) / n;
4359  double histxyij = (histxy(i, j)) / n;
4360  if (histxyij > 0)
4361  retval += histxyij * log(histxyij / (histxi * histyj)) /
4362  LOG2;
4363  }
4364  }
4365 
4366  return retval;
4367  }
4368  else
4369  return 0;
4370 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define A3D_ELEM(V, k, i, j)
void log(Image< double > &op)
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
#define XSIZE(v)
#define ZSIZE(v)
#define SPEED_UP_temps
Definition: xmipp_macros.h:419
#define j
constexpr double LOG2
Definition: filters.h:33
#define FOR_ALL_ELEMENTS_IN_COMMON_IN_ARRAY3D(V1, V2)
int * n

◆ noisyZonesFilter()

void noisyZonesFilter ( MultidimArray< double > &  I,
int  kernelSize = 10 
)

Transforms I to a binary mask with 0 where both variance and mean are high.

Definition at line 870 of file filters.cpp.

871 {
872  int kernelSize_2 = kernelSize/2;
873  MultidimArray<double> kernel;
874  kernel.resize(kernelSize,kernelSize);
875  kernel.setXmippOrigin();
876 
877  MultidimArray<double> mAvg=I;
878  MultidimArray<double> mVar=I;
879  double stdKernel;
880  double varKernel;
881  double avgKernel;
882  double min_val;
883  double max_val;
884  int x0;
885  int y0;
886  int xF;
887  int yF;
888 
889  for (int i=kernelSize_2; i<(int)YSIZE(I); i+=kernelSize_2)
890  for (int j=kernelSize_2; j<(int)XSIZE(I); j+=kernelSize_2)
891  {
892  x0 = j-kernelSize_2;
893  y0 = i-kernelSize_2;
894  xF = j+kernelSize_2-1;
895  yF = i+kernelSize_2-1;
896 
897  if (x0 < 0)
898  x0 = 0;
899  if (xF > XSIZE(I))
900  xF = XSIZE(I);
901  if (y0 < 0)
902  y0 = 0;
903  if (yF > YSIZE(I))
904  yF = YSIZE(I);
905 
906  I.window(kernel, y0, x0, yF, xF);
907  kernel.computeStats(avgKernel, stdKernel, min_val, max_val);
908  varKernel = stdKernel*stdKernel;
909 
910  DIRECT_A2D_ELEM(mAvg, i, j) = avgKernel*avgKernel;
911  DIRECT_A2D_ELEM(mVar, i, j) = varKernel;
912  }
913 
914  // filtering to fill the matrices (convolving with a Gaussian)
915  FourierFilter filter;
916  filter.FilterShape = REALGAUSSIAN;
917  filter.FilterBand = LOWPASS;
918  filter.w1 = kernelSize_2;
919  filter.applyMaskSpace(mAvg);
920  filter.applyMaskSpace(mVar);
921 
922  // // Draw to debug
923  // Image<double> imAvg(mAvg), imVar(mVar);
924  // imAvg.write("AvgFilter.mrc");
925  // imVar.write("VarFilter.mrc");
926 
927  // Working in a auxilary windows to avoid borders bad defined
928  auto ysize = static_cast<int>YSIZE(I);
929  auto xsize = static_cast<int>XSIZE(I);
930  MultidimArray<double> mAvgAux(ysize-kernelSize,xsize-kernelSize);
931  MultidimArray<double> mVarAux(ysize-kernelSize,xsize-kernelSize);
932  mAvgAux.setXmippOrigin();
933  mVarAux.setXmippOrigin();
934  mAvg.window(mAvgAux,STARTINGY(mAvg)+kernelSize_2, STARTINGX(mAvg)+kernelSize_2,
935  FINISHINGY(mAvg)-kernelSize_2, FINISHINGX(mAvg)-kernelSize_2);
936  mVar.window(mVarAux,STARTINGY(mVar)+kernelSize_2, STARTINGX(mVar)+kernelSize_2,
937  FINISHINGY(mVar)-kernelSize_2, FINISHINGX(mVar)-kernelSize_2);
938 
939  // Refiltering to get a smoother distribution
940  // filter.w1 = XSIZE(I)/40;
941  // filter.applyMaskSpace(mAvgAux);
942  // filter.applyMaskSpace(mVarAux);
943 
944  // Binarization
945  MultidimArray<double> mAvgAuxBin = mAvgAux;
946  MultidimArray<double> mVarAuxBin = mVarAux;
947  EntropySegmentation(mVarAuxBin);
948  // EntropySegmentation(mAvgAuxBin);
949  float th = EntropySegmentation(mAvgAuxBin);
950  mAvgAuxBin.binarize(th*0.92);
951  mAvgAuxBin = 1-mAvgAuxBin;
952  // std::cout << "binarize threshold = " << th << std::endl;
953 
954  // Returning to the previous windows size
955  MultidimArray<double> mAvgBin = mAvg;
956  MultidimArray<double> mVarBin = mVar;
957  mAvgAuxBin.window(mAvgBin, STARTINGY(mVar), STARTINGX(mVar),
958  FINISHINGY(mVar), FINISHINGX(mVar));
959  mVarAuxBin.window(mVarBin, STARTINGY(mVar), STARTINGX(mVar),
960  FINISHINGY(mVar), FINISHINGX(mVar));
961 
962  // // Draw to debug
963  // Image<double> imAvgBin(mAvgBin), imVarBin(mVarBin);
964  // imAvgBin.write("noisyZoneFilter_AVGmask.mrc");
965  // imVarBin.write("noisyZoneFilter_VARmask.mrc");
966 
967  // Combining both masks
968  I = 1-(mVarBin*mAvgBin);
969 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define FINISHINGX(v)
void computeStats(double &avg, double &stddev, T &minval, T &maxval) const
#define DIRECT_A2D_ELEM(v, i, j)
#define STARTINGX(v)
#define i
#define STARTINGY(v)
void window(MultidimArray< T1 > &result, int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T1 init_value=0) const
#define y0
#define x0
void binarize(double val=0, double accuracy=XMIPP_EQUAL_ACCURACY, MultidimArray< int > *mask=NULL)
#define XSIZE(v)
#define xF
#define j
#define FINISHINGY(v)
#define REALGAUSSIAN
double EntropySegmentation(MultidimArray< double > &V)
Definition: filters.cpp:1078
#define yF
#define LOWPASS
void applyMaskSpace(MultidimArray< double > &v)

◆ OtsuSegmentation()

double OtsuSegmentation ( MultidimArray< double > &  V)

Segment an object using Otsu's method

Otsu's method determines a threshold such that the variance of the two classes is minimized

http://www.biomecardio.com/matlab/otsu.html

Definition at line 1028 of file filters.cpp.

1029 {
1030  // V.checkDimension(3);
1031 
1032  // Compute the probability density function
1033  Histogram1D hist;
1034  hist.clear();
1035  compute_hist(V, hist, 200);
1036  hist /= hist.sum();
1037 
1038  // Compute the cumulative 0th and 1st order moments
1039  double x;
1040  MultidimArray<double> mom0;
1041  MultidimArray<double> mom1;
1042  mom0.initZeros(XSIZE(hist));
1043  mom1.initZeros(XSIZE(hist));
1044  mom0(0) = hist(0);
1045  hist.index2val(0, x);
1046  mom1(0) = hist(0) * x;
1047  for (size_t i = 1; i < XSIZE(mom0); i++)
1048  {
1049  mom0(i) = mom0(i - 1) + hist(i);
1050  hist.index2val(i, x);
1051  mom1(i) = mom1(i - 1) + hist(i) * x;
1052  }
1053 
1054  // Maximize sigma2B
1055  double bestSigma2B = -1;
1056  int ibestSigma2B = -1;
1057  for (size_t i = 0; i < XSIZE(hist) - 1; i++)
1058  {
1059  double w1 = mom0(i);
1060  double w2 = 1 - mom0(i);
1061  double mu1 = mom1(i);
1062  double mu2 = mom1(XSIZE(mom1) - 1) - mom1(i);
1063  double sigma2B = w1 * w2 * (mu1 - mu2) * (mu1 - mu2);
1064  if (sigma2B > bestSigma2B)
1065  {
1066  bestSigma2B = sigma2B;
1067  ibestSigma2B = i;
1068  }
1069  }
1070 
1071  hist.index2val(ibestSigma2B, x);
1072  V.binarize(x);
1073 
1074  return x;
1075 }
void clear()
Definition: histogram.cpp:40
doublereal * x
#define i
void index2val(double i, double &v) const
Definition: histogram.h:295
void compute_hist(const MultidimArrayGeneric &array, Histogram1D &hist, int no_steps)
Definition: histogram.cpp:572
void binarize(double val=0, double accuracy=XMIPP_EQUAL_ACCURACY, MultidimArray< int > *mask=NULL)
int mu1
#define XSIZE(v)
void initZeros(const MultidimArray< T1 > &op)
double sum() const

◆ pixelDesvFilter()

template<typename T >
void pixelDesvFilter ( MultidimArray< T > &  V,
double  thresFactor 
)

Remove bad pixels.

A boundaries median filter is applied at those pixels whose value is out of range given by thresFactor * std.

Definition at line 1378 of file filters.h.

1379 {
1380  if (thresFactor > 0 )
1381  {
1382  double avg;
1383  double stddev;
1384  double high;
1385  double low;
1386  T dummy;
1387  MultidimArray<char> mask(ZSIZE(V), YSIZE(V), XSIZE(V));
1388  avg = stddev = low = high = 0;
1389  V.computeStats(avg, stddev, dummy, dummy);//min and max not used
1390  low = (avg - thresFactor * stddev);
1391  high = (avg + thresFactor * stddev);
1392 
1394  {
1395  double x = DIRECT_MULTIDIM_ELEM(V, n);
1396  DIRECT_MULTIDIM_ELEM(mask, n) = (x < low || x > high) ? 1 : 0;
1397  }
1398  boundMedianFilter(V, mask);
1399  }
1400 }
#define YSIZE(v)
void computeStats(double &avg, double &stddev, T &minval, T &maxval) const
doublereal * x
#define XSIZE(v)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
double dummy
void boundMedianFilter(MultidimArray< T > &V, const MultidimArray< char > &mask, int n=0)
Definition: filters.h:1309
int * n

◆ regionGrowing2D()

void regionGrowing2D ( const MultidimArray< double > &  I_in,
MultidimArray< double > &  I_out,
int  i,
int  j,
float  stop_colour = 1,
float  filling_colour = 1,
bool  less = true,
int  neighbourhood = 8 
)

Region growing for images

Given a position inside an image, this function grows a region with (filling_colour) until it finds a border of value (stop_colour). If the point is outside the image then nothing is done.

If less is true the region is grown in sucha a way that all voxels in its border are greater than the region voxels. If less is false the region is grown so that all voxels on its border are smaller than the region voxels.

Valid neighbourhoods are 4 or 8.

Definition at line 340 of file filters.cpp.

343 {
344  I_in.checkDimension(2);
345 
346  std::list<Coordinate2D> iNeighbours; /* A list for neighbour pixels */
347  int iCurrenti;
348  int iCurrentj; /* Coordinates of the current pixel considered */
349 
350  /* First task is copying the input image into the output one */
351  I_out = I_in;
352 
353  /**** Then the region growing is done ****/
354  /* Insert at the beginning of the list the seed coordinates */
355  Coordinate2D coord;
356  coord.ii = i;
357  coord.jj = j;
358  iNeighbours.push_front(coord);
359 
360  /* Fill the seed coordinates */
361  A2D_ELEM(I_out, i, j) = filling_colour;
362 
363  while (!iNeighbours.empty())
364  {
365  /* Take the current pixel to explore */
366  coord = iNeighbours.front();
367  iNeighbours.pop_front();
368  iCurrenti = coord.ii;
369  iCurrentj = coord.jj;
370 
371 #define CHECK_POINT(i,j) \
372  { \
373  int I=i; \
374  int J=j; \
375  if (INSIDEXY(I_out,J,I)) { \
376  double pixel=A2D_ELEM(I_out,I,J);\
377  if (pixel!=filling_colour) \
378  if ((less && pixel < stop_colour) || \
379  (!less && pixel > stop_colour)) { \
380  coord.ii=I; \
381  coord.jj=J; \
382  A2D_ELEM (I_out,coord.ii,coord.jj)=filling_colour; \
383  iNeighbours.push_front(coord); \
384  } \
385  } \
386  }
387 
388  /* Make the exploration of the pixel's neighbours */
389  CHECK_POINT(iCurrenti, iCurrentj - 1);
390  CHECK_POINT(iCurrenti, iCurrentj + 1);
391  CHECK_POINT(iCurrenti - 1, iCurrentj);
392  CHECK_POINT(iCurrenti + 1, iCurrentj);
393  if (neighbourhood == 8)
394  {
395  CHECK_POINT(iCurrenti - 1, iCurrentj - 1);
396  CHECK_POINT(iCurrenti - 1, iCurrentj + 1);
397  CHECK_POINT(iCurrenti + 1, iCurrentj - 1);
398  CHECK_POINT(iCurrenti + 1, iCurrentj + 1);
399  }
400  }
401 }
#define A2D_ELEM(v, i, j)
#define i
#define j
#define CHECK_POINT(i, j)

◆ removeSmallComponents()

void removeSmallComponents ( MultidimArray< double > &  I,
int  size,
int  neighbourhood = 8 
)

Remove connected components

Remove connected components smaller than a given size. They are set to 0.

Definition at line 689 of file filters.cpp.

691 {
692  MultidimArray<double> label;
693  int imax;
694  if (ZSIZE(I)==1)
695  imax=labelImage2D(I, label, neighbourhood);
696  else
697  imax=labelImage3D(I, label);
698  MultidimArray<int> nlabel(imax + 1);
700  {
701  int l=(int)DIRECT_MULTIDIM_ELEM(label,n);
702  DIRECT_A1D_ELEM(nlabel,l)++;
703  }
705  {
706  int l=(int)DIRECT_MULTIDIM_ELEM(label,n);
707  if (DIRECT_A1D_ELEM(nlabel,l)<size)
708  DIRECT_MULTIDIM_ELEM(I,n)=0;
709  }
710 }
#define DIRECT_A1D_ELEM(v, i)
#define FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(v)
#define ZSIZE(v)
#define DIRECT_MULTIDIM_ELEM(v, n)
int labelImage2D(const MultidimArray< double > &I, MultidimArray< double > &label, int neighbourhood)
Definition: filters.cpp:648
int labelImage3D(const MultidimArray< double > &V, MultidimArray< double > &label)
Definition: filters.cpp:669
int * n

◆ rms()

template<typename T >
double rms ( const MultidimArray< T > &  x,
const MultidimArray< T > &  y,
const MultidimArray< int > *  mask = nullptr,
MultidimArray< double > *  Contributions = nullptr 
)

RMS nD

Definition at line 725 of file filters.h.

729 {
731 
732  double retval = 0;
733  double aux;
734  int n = 0;
735 
736  // If contributions are desired
737  if (Contributions != nullptr)
738  {
740  {
741  if (mask != nullptr)
742  if (!(*mask)(k, i, j))
743  continue;
744 
745  aux = (A3D_ELEM(x, k, i, j) - A3D_ELEM(y, k, i, j)) *
746  (A3D_ELEM(x, k, i, j) - A3D_ELEM(y, k, i, j));
747  A3D_ELEM(*Contributions, k, i, j) = aux;
748  retval += aux;
749  n++;
750  }
751 
752  FOR_ALL_ELEMENTS_IN_ARRAY3D(*Contributions)
753  A3D_ELEM(*Contributions, k, i, j) = sqrt(A3D_ELEM(*Contributions,
754  k, i, j) / n);
755  }
756  else
757  {
759  {
760  if (mask != nullptr)
761  if (!(*mask)(k, i, j))
762  continue;
763 
764  retval += (A3D_ELEM(x, k, i, j) - A3D_ELEM(y, k, i, j)) *
765  (A3D_ELEM(x, k, i, j) - A3D_ELEM(y, k, i, j));
766  n++;
767  }
768  }
769 
770  if (n != 0)
771  return sqrt(retval / n);
772  else
773  return 0;
774 }
void sqrt(Image< double > &op)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
#define j
#define SPEED_UP_tempsInt
Definition: xmipp_macros.h:408
#define FOR_ALL_ELEMENTS_IN_COMMON_IN_ARRAY3D(V1, V2)
int * n

◆ rotationalInvariantMoments()

void rotationalInvariantMoments ( const MultidimArray< double > &  img,
const MultidimArray< int > *  mask,
MultidimArray< double > &  v_out 
)

Rotational invariant moments

The mask and the image are supposed to be of the same shape. If no mask is provided, the moments are computed on the whole image. The moments are measured with respect to the origin of the image.

These moments have been taken from http://www.cs.cf.ac.uk/Dave/Vision_lecture/node36.html (moments 1 to 5).

Definition at line 2900 of file filters.cpp.

2902 {
2903  img.checkDimension(2);
2904 
2905  // Prepare some variables
2906  double m_11 = 0;
2907  double m_02 = 0;
2908  double m_20 = 0;
2909  double m_12 = 0;
2910  double m_21 = 0;
2911  double m_03 = 0;
2912  double m_30 = 0;
2913  double normalize_x = 2.0 / XSIZE(img);
2914  double normalize_y = 2.0 / YSIZE(img);
2915 
2916  // Compute low-level moments
2918  {
2919  if (mask != nullptr)
2920  if (!(*mask)(i, j))
2921  continue;
2922  double val = img(i, j);
2923  double dx = j * normalize_x;
2924  double dy = i * normalize_y;
2925  double dx2 = dx * dx;
2926  double dx3 = dx2 * dx;
2927  double dy2 = dy * dy;
2928  double dy3 = dy2 * dy;
2929  // m_00+=val;
2930  m_11 += val * dx * dy;
2931  m_02 += val * dy2;
2932  m_20 += val * dx2;
2933  m_12 += val * dx * dy2;
2934  m_21 += val * dx2 * dy;
2935  m_03 += val * dy3;
2936  m_30 += val * dx3;
2937  }
2938  //m_11/=m_00; m_02/=m_00; m_20/=m_00;
2939  //m_12/=m_00; m_21/=m_00; m_03/=m_00; m_30/=m_00;
2940 
2941  // Compute high-level rotational invariant moments
2942  v_out.resize(5);
2943  v_out(0) = m_20 + m_02;
2944  v_out(1) = (m_20 - m_02) * (m_20 - m_02) + 4 * m_11 * m_11;
2945  v_out(2) = (m_30 - 3 * m_12) * (m_30 - 3 * m_12)
2946  + (3 * m_21 - m_03) * (3 * m_21 - m_03);
2947  v_out(3) = (m_30 + m_12) * (m_30 + m_12) + (m_21 + m_03) * (m_21 + m_03);
2948  v_out(4) =
2949  (m_30 - 3 * m_12) * (m_30 + m_12)
2950  * ((m_30 + m_12) * (m_30 + m_12)
2951  - 3 * (m_21 + m_03) * (m_21 + m_03))
2952  + (3 * m_21 - m_03) * (m_21 + m_03)
2953  * (3 * (m_30 + m_12) * (m_30 + m_12)
2954  - (m_21 + m_03) * (m_21 + m_03));
2955  /*
2956  v_out( 5)=(m_20+m_02)*(
2957  (m_30+m_12)*(m_30+m_12)
2958  -3*(m_21+m_03)*(m_21+m_03))
2959  +4*m_11*(m_30+m_12)*(m_03+m_21);
2960  v_out( 6)=(3*m_21-m_03)*(m_12+m_30)*(
2961  (m_30+m_12)*(m_30+m_12)
2962  -3*(m_21+m_03)*(m_21+m_03))
2963  -(m_30-3*m_12)*(m_12+m_03)*(
2964  3*(m_30+m_12)*(m_30+m_12)
2965  -(m_21+m_03)*(m_21+m_03));
2966  */
2967 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define XSIZE(v)
double dx
#define j

◆ smoothingShah()

void smoothingShah ( MultidimArray< double > &  img,
MultidimArray< double > &  surface_strength,
MultidimArray< double > &  edge_strength,
const Matrix1D< double > &  W,
int  OuterLoops,
int  InnerLoops,
int  RefinementLoops,
bool  adjust_range = true 
)

Mumford-Shah smoothing

This function simultaneously smooths and segments an image using non-linear diffusion. Mumford-&-Shah's functional minimization algorithm is used to detect region boundaries and relax image smoothness constraints near these discontinuities. The functional minimized is:

E = W0*(f-d)*(f-d) (data matching)

  • W1*(fx*fx + fy*fy)*(1-s)*(1-s) (1st deriv smooth)
  • W2*(s*s) (edge strengths)
  • W3*(sx*sx + sy*sy) (edge smoothness)

The program diffusion from KUIM (developed by J. Gaush, U. Kansas) was used as the "seed".

Paper: Teboul, et al. IEEE-Trans. on Image Proc. Vol. 7, 387-397.

Definition at line 2720 of file filters.cpp.

2725 {
2726 
2727  img.checkDimension(2);
2728 
2729  typeCast(img, surface_strength);
2730  if (adjust_range)
2731  surface_strength.rangeAdjust(0, 1);
2732  edge_strength.resizeNoCopy(img);
2733 
2734  for (int k = 1; k <= RefinementLoops; k++)
2735  {
2736  // Initialize Edge Image.
2737  edge_strength.initZeros();
2738 
2739  double diffsurface = MAXFLOAT; // Reset surface difference
2740  for (int i = 0;
2741  ((i < OuterLoops) && OuterLoops)
2742  || ((diffsurface > SHAH_CONVERGENCE_THRESHOLD)
2743  && !OuterLoops); i++)
2744  {
2745 
2746  /* std::cout << "Iteration ..." << i+1;*/
2747  /* Iteratively update surface estimate */
2748  for (int j = 0; j < InnerLoops; j++)
2749  diffsurface = Update_surface_Shah(img, surface_strength,
2750  edge_strength, W);
2751 
2752  /* Iteratively update edge estimate */
2753  for (int j = 0; j < InnerLoops; j++)
2754  Update_edge_Shah(img, surface_strength, edge_strength, k, W);
2755 
2756  /* Calculate new functional energy */
2757  Shah_energy(img, surface_strength, edge_strength, k, W);
2758  }
2759  }
2760 }
double Shah_energy(const MultidimArray< double > &img, const MultidimArray< double > &surface_strength, const MultidimArray< double > &edge_strength, double K, const Matrix1D< double > &W)
Definition: filters.cpp:2511
void resizeNoCopy(const MultidimArray< T1 > &v)
void rangeAdjust(T minF, T maxF)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
double Update_edge_Shah(MultidimArray< double > &img, MultidimArray< double > &surface_strength, MultidimArray< double > &edge_strength, double K, const Matrix1D< double > &W)
Definition: filters.cpp:2657
#define MAXFLOAT
Definition: data_types.h:47
#define j
constexpr double SHAH_CONVERGENCE_THRESHOLD
Definition: filters.cpp:2719
double Update_surface_Shah(MultidimArray< double > &img, MultidimArray< double > &surface_strength, MultidimArray< double > &edge_strength, const Matrix1D< double > &W)
Definition: filters.cpp:2577
void typeCast(const Matrix1D< T1 > &v1, Matrix1D< T2 > &v2)
Definition: matrix1d.h:1227
void initZeros(const MultidimArray< T1 > &op)

◆ SmoothResize()

void SmoothResize ( byte srcpic8,
byte destpic8,
size_t  swide,
size_t  shigh,
size_t  dwide,
size_t  dhigh 
)

Resize of a 8-bit image

Definition at line 93 of file xvsmooth.cpp.

93  {
94  /* generic interface to Smooth and ColorDither code.
95  given an 8-bit-per, swide * shigh image with colormap rmap,gmap,bmap,
96  will generate a new 8-bit-per, dwide * dhigh image, which is dithered
97  using colors found in rdmap, gdmap, bdmap arrays */
98 
99  /* returns ptr to a dwide*dhigh array of bytes, or NULL on failure */
100  byte * picSmooth = Smooth(picSrc8, swide, shigh, dwide, dhigh);
101  if (picSmooth) {
102  DoColorDither(picSmooth, destpic8, dwide, dhigh);
103  free(picSmooth);
104  }
105 }
void DoColorDither(byte *picSmooth, byte *&picDithered, size_t w, size_t h)
Definition: xvsmooth.cpp:297
byte * Smooth(byte *picSrc8, size_t swide, size_t shigh, size_t dwide, size_t dhigh)
Definition: xvsmooth.cpp:108
free((char *) ob)
unsigned char byte
Definition: xvsmooth.cpp:73

◆ sort()

template<typename T >
void sort ( a,
b,
c,
MultidimArray< T > &  v 
)

Harmonic decomposition

Definition at line 798 of file filters.h.

799 {
800  if (a < b)
801  if (b < c)
802  {
803  DIRECT_MULTIDIM_ELEM(v,0) = a;
804  DIRECT_MULTIDIM_ELEM(v,1) = b;
805  DIRECT_MULTIDIM_ELEM(v,2) = c;
806  }
807  else if (a < c)
808  {
809  DIRECT_MULTIDIM_ELEM(v,0) = a;
810  DIRECT_MULTIDIM_ELEM(v,1) = c;
811  DIRECT_MULTIDIM_ELEM(v,2) = b;
812  }
813  else
814  {
815  DIRECT_MULTIDIM_ELEM(v,0) = c;
816  DIRECT_MULTIDIM_ELEM(v,1) = a;
817  DIRECT_MULTIDIM_ELEM(v,2) = b;
818  }
819  else if (a < c)
820  {
821  DIRECT_MULTIDIM_ELEM(v,0) = b;
822  DIRECT_MULTIDIM_ELEM(v,1) = a;
823  DIRECT_MULTIDIM_ELEM(v,2) = c;
824  }
825  else if (b < c)
826  {
827  DIRECT_MULTIDIM_ELEM(v,0) = b;
828  DIRECT_MULTIDIM_ELEM(v,1) = c;
829  DIRECT_MULTIDIM_ELEM(v,2) = a;
830  }
831  else
832  {
833  DIRECT_MULTIDIM_ELEM(v,0) = c;
834  DIRECT_MULTIDIM_ELEM(v,1) = b;
835  DIRECT_MULTIDIM_ELEM(v,2) = a;
836  }
837 }
doublereal * c
doublereal * b
#define DIRECT_MULTIDIM_ELEM(v, n)
doublereal * a

◆ substractBackgroundPlane()

void substractBackgroundPlane ( MultidimArray< double > &  I)

Subtract background

The background is computed as the plane which best fits all density values, then this plane is subtracted from the image.

Definition at line 40 of file filters.cpp.

41 {
42 
43  I.checkDimension(2);
44 
45  Matrix2D<double> A(3, 3);
48 
49  // Solve the plane 'x'
50  A.initZeros();
51  b.initZeros();
53  {
54  A(0, 0) += j * j;
55  A(0, 1) += j * i;
56  A(0, 2) += j;
57  A(1, 1) += i * i;
58  A(1, 2) += i;
59  A(2, 2) += 1;
60  b(0) += j * A2D_ELEM(I, i, j);
61  b(1) += i * A2D_ELEM(I, i, j);
62  b(2) += A2D_ELEM(I, i, j);
63  }
64  A(1, 0) = A(0, 1);
65  A(2, 0) = A(0, 2);
66  A(2, 1) = A(1, 2);
67  solve(A, b, x);
68 
69  // Now subtract the plane
71  A2D_ELEM(I, i, j) -= x(0) * i + x(1) * j + x(2);
72 }
#define A2D_ELEM(v, i, j)
doublereal * x
#define i
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
void solve(const Matrix2D< T > &A, const Matrix2D< T > &b, Matrix2D< T > &result)
doublereal * b
#define j

◆ substractBackgroundRollingBall()

void substractBackgroundRollingBall ( MultidimArray< double > &  I,
int  radius 
)

Subtract background

The background is computed as a rolling ball operation with a ball with this radius. The radius is typically Xdim/10.

This code has been implemented after the one of "Subtract background" in ImageJ.

Definition at line 75 of file filters.cpp.

76 {
77 
78  I.checkDimension(2);
79 
80  // Build the ball
81  int arcTrimPer;
82  int shrinkFactor;
83  if (radius <= 10)
84  {
85  shrinkFactor = 1;
86  arcTrimPer = 24; // trim 24% in x and y
87  }
88  else if (radius <= 30)
89  {
90  shrinkFactor = 2;
91  arcTrimPer = 24; // trim 24% in x and y
92  }
93  else if (radius <= 100)
94  {
95  shrinkFactor = 4;
96  arcTrimPer = 32; // trim 32% in x and y
97  }
98  else
99  {
100  shrinkFactor = 8;
101  arcTrimPer = 40; // trim 40% in x and y
102  }
103 
104  double smallballradius = radius / shrinkFactor;
105  if (smallballradius < 1)
106  smallballradius = 1;
107  double r2 = smallballradius * smallballradius;
108  int xtrim = (int) (arcTrimPer * smallballradius) / 100; // only use a patch of the rolling ball
109  int halfWidth = ROUND(smallballradius - xtrim);
110  int ballWidth = 2 * halfWidth + 1;
111  MultidimArray<double> ball(ballWidth, ballWidth);
112  ball.setXmippOrigin();
114  {
115  double temp = r2 - i * i - j * j;
116  ball(i, j) = temp > 0. ? sqrt(temp) : 0.;
117  }
118 
119  // Shrink the image: each point in the shrinked image is the
120  // minimum of its neighbourhood
121  int sXdim = (XSIZE(I) + shrinkFactor - 1) / shrinkFactor;
122  int sYdim = (YSIZE(I) + shrinkFactor - 1) / shrinkFactor;
123  MultidimArray<double> shrinkI(sYdim, sXdim);
124  shrinkI.setXmippOrigin();
125  for (int ySmall = 0; ySmall < sYdim; ySmall++)
126  {
127  for (int xSmall = 0; xSmall < sXdim; xSmall++)
128  {
129  double minVal = 1e38;
130  for (int j = 0, y = shrinkFactor * ySmall;
131  j < shrinkFactor && y < (int)YSIZE(I); j++, y++)
132  for (int k = 0, x = shrinkFactor * xSmall;
133  k < shrinkFactor && x < (int)XSIZE(I); k++, x++)
134  {
135  double thispixel = DIRECT_A2D_ELEM(I,y,x);
136  if (thispixel < minVal)
137  minVal = thispixel;
138  }
139  DIRECT_A2D_ELEM(shrinkI,ySmall,xSmall) = minVal;
140  }
141  }
142 
143  // Now roll the ball
144  radius = ballWidth / 2;
145  MultidimArray<double> Irolled;
146  Irolled.resizeNoCopy(shrinkI);
147  Irolled.initConstant(-500);
148  for (int yb = -radius; yb < (int)YSIZE(shrinkI) + radius; yb++)
149  {
150  // Limits of the ball
151  int y0 = yb - radius;
152  if (y0 < 0)
153  y0 = 0;
154  int y0b = y0 - yb + radius; //y coordinate in the ball corresponding to y0
155  int yF = yb + radius;
156  if (yF >= (int)YSIZE(shrinkI))
157  yF = (int)YSIZE(shrinkI) - 1;
158 
159  for (int xb = -radius; xb < (int)XSIZE(shrinkI) + radius; xb++)
160  {
161  // Limits of the ball
162  int x0 = xb - radius;
163  if (x0 < 0)
164  x0 = 0;
165  int x0b = x0 - xb + radius;
166  int xF = xb + radius;
167  if (xF >= (int)XSIZE(shrinkI))
168  xF = (int)XSIZE(shrinkI) - 1;
169 
170  double z = 1e38;
171  for (int yp = y0, ybp = y0b; yp <= yF; yp++, ybp++)
172  for (int xp = x0, xbp = x0b; xp <= xF; xp++, xbp++)
173  {
174  double zReduced = DIRECT_A2D_ELEM(shrinkI,yp,xp)
175  - DIRECT_A2D_ELEM(ball,ybp,xbp);
176  if (z > zReduced)
177  z = zReduced;
178  }
179  for (int yp = y0, ybp = y0b; yp <= yF; yp++, ybp++)
180  for (int xp = x0, xbp = x0b; xp <= xF; xp++, xbp++)
181  {
182  double zMin = z + DIRECT_A2D_ELEM(ball,ybp,xbp);
183  if (DIRECT_A2D_ELEM(Irolled,yp,xp) < zMin)
184  DIRECT_A2D_ELEM(Irolled,yp,xp) = zMin;
185  }
186  }
187  }
188 
189  // Now rescale the background
190  MultidimArray<double> bgEnlarged;
191  scaleToSize(xmipp_transformation::LINEAR, bgEnlarged, Irolled, XSIZE(I), YSIZE(I));
192  bgEnlarged.copyShape(I);
193  I -= bgEnlarged;
194 }
#define YSIZE(v)
void resizeNoCopy(const MultidimArray< T1 > &v)
void sqrt(Image< double > &op)
static double * y
#define DIRECT_A2D_ELEM(v, i, j)
void initConstant(T val)
doublereal * x
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define FOR_ALL_ELEMENTS_IN_ARRAY2D(m)
#define y0
#define x0
#define XSIZE(v)
double z
#define ROUND(x)
Definition: xmipp_macros.h:210
#define xF
#define j
void scaleToSize(int SplineDegree, MultidimArrayGeneric &V2, const MultidimArrayGeneric &V1, int Xdim, int Ydim, int Zdim)
void copyShape(const MultidimArrayBase &m)
float r2
#define yF
double radius
Spatial radius in Universal System units.
Definition: blobs.h:115

◆ tomographicDiffusion()

double tomographicDiffusion ( MultidimArray< double > &  V,
const Matrix1D< double > &  alpha,
double  lambda 
)

Tomographic diffusion

The direction of the tilt axis must be taken into account in the definition of the diffusion constants alpha.

The function returns the value of the regularization term.

Definition at line 2764 of file filters.cpp.

2766 {
2767  V.checkDimension(3);
2768 
2769  double alphax = XX(alpha);
2770  double alphay = YY(alpha);
2771  double alphaz = ZZ(alpha);
2772  double diffx;
2773  double diffy;
2774  double diffz;
2775 
2776  // Compute regularization error
2777  double regError = 0;
2778  for (size_t z = 1; z < ZSIZE(V) - 1; z++)
2779  for (size_t y = 1; y < YSIZE(V) - 1; y++)
2780  for (size_t x = 1; x < XSIZE(V) - 1; x++)
2781  {
2782  diffx = DIRECT_A3D_ELEM(V,z,y,x+1) - DIRECT_A3D_ELEM(V,z,y,x-1);
2783  diffy = DIRECT_A3D_ELEM(V,z,y+1,x) - DIRECT_A3D_ELEM(V,z,y-1,x);
2784  diffz = DIRECT_A3D_ELEM(V,z+1,y,x) - DIRECT_A3D_ELEM(V,z-1,y,x);
2785  regError += sqrt(
2786  alphax * diffx * diffx + alphay * diffy * diffy
2787  + alphaz * diffz * diffz);
2788  }
2789  regError *= 0.5;
2790 
2791  // Compute the gradient of the regularization error
2792  MultidimArray<double> gradient;
2793  gradient.initZeros(V);
2794  for (size_t z = 2; z < ZSIZE(V) - 2; z++)
2795  for (size_t y = 2; y < YSIZE(V) - 2; y++)
2796  for (size_t x = 2; x < XSIZE(V) - 2; x++)
2797  {
2798  // First term
2799  double V000 = DIRECT_A3D_ELEM(V,z,y,x);
2800  double V_200 = DIRECT_A3D_ELEM(V,z,y,x-2);
2801  double V_110 = DIRECT_A3D_ELEM(V,z,y+1,x-1);
2802  double V_1_10 = DIRECT_A3D_ELEM(V,z,y-1,x-1);
2803  double V_101 = DIRECT_A3D_ELEM(V,z+1,y,x-1);
2804  double V_10_1 = DIRECT_A3D_ELEM(V,z-1,y,x-1);
2805  diffx = V000 - V_200;
2806  diffy = V_110 - V_1_10;
2807  diffz = V_101 - V_10_1;
2808  double t1 = diffx
2809  / sqrt(
2810  alphax * diffx * diffx + alphay * diffy * diffy
2811  + alphaz * diffz * diffz);
2812 
2813  // Second term
2814  double V200 = DIRECT_A3D_ELEM(V,z,y,x+2);
2815  double V110 = DIRECT_A3D_ELEM(V,z,y+1,x+1);
2816  double V1_10 = DIRECT_A3D_ELEM(V,z,y-1,x+1);
2817  double V101 = DIRECT_A3D_ELEM(V,z+1,y,x+1);
2818  double V10_1 = DIRECT_A3D_ELEM(V,z-1,y,x+1);
2819  diffx = V200 - V000;
2820  diffy = V110 - V1_10;
2821  diffz = V101 - V10_1;
2822  double t2 = diffx
2823  / sqrt(
2824  alphax * diffx * diffx + alphay * diffy * diffy
2825  + alphaz * diffz * diffz);
2826 
2827  // Third term
2828  double V0_20 = DIRECT_A3D_ELEM(V,z,y-2,x);
2829  double V0_11 = DIRECT_A3D_ELEM(V,z+1,y-1,x);
2830  double V0_1_1 = DIRECT_A3D_ELEM(V,z-1,y-1,x);
2831  diffx = V1_10 - V_1_10;
2832  diffy = V000 - V0_20;
2833  diffz = V0_11 - V0_1_1;
2834  double t3 = diffy
2835  / sqrt(
2836  alphax * diffx * diffx + alphay * diffy * diffy
2837  + alphaz * diffz * diffz);
2838 
2839  // Fourth term
2840  double V020 = DIRECT_A3D_ELEM(V,z,y+2,x);
2841  double V011 = DIRECT_A3D_ELEM(V,z+1,y+1,x);
2842  double V01_1 = DIRECT_A3D_ELEM(V,z-1,y+1,x);
2843  diffx = V110 - V_110;
2844  diffy = V020 - V000;
2845  diffz = V011 - V01_1;
2846  double t4 = diffy
2847  / sqrt(
2848  alphax * diffx * diffx + alphay * diffy * diffy
2849  + alphaz * diffz * diffz);
2850 
2851  // Fifth term
2852  double V00_2 = DIRECT_A3D_ELEM(V,z-2,y,x);
2853  diffx = V10_1 - V_10_1;
2854  diffy = V01_1 - V0_1_1;
2855  diffz = V000 - V00_2;
2856  double t5 = diffz
2857  / sqrt(
2858  alphax * diffx * diffx + alphay * diffy * diffy
2859  + alphaz * diffz * diffz);
2860 
2861  // Sixth term
2862  double V002 = DIRECT_A3D_ELEM(V,z+2,y,x);
2863  diffx = V101 - V_101;
2864  diffy = V011 - V0_11;
2865  diffz = V002 - V000;
2866  double t6 = diffz
2867  / sqrt(
2868  alphax * diffx * diffx + alphay * diffy * diffy
2869  + alphaz * diffz * diffz);
2870 
2871  // Compute gradient
2872  DIRECT_A3D_ELEM(gradient,z,y,x) = 0.5
2873  * (alphax * (t1 - t2) + alphay * (t3 - t4)
2874  + alphaz * (t5 - t6));
2875  }
2876 #ifdef DEBUG
2877  VolumeXmipp save;
2878  save()=V;
2879  save.write("PPPvolume.vol");
2880  save()=gradient;
2881  save.write("PPPgradient.vol");
2882  std::cout << "Press any key\n";
2883  char c;
2884  std::cin >> c;
2885 #endif
2886 
2887  // Update volume
2888  for (size_t z = 2; z < ZSIZE(V) - 2; z++)
2889  for (size_t y = 2; y < YSIZE(V) - 2; y++)
2890  for (size_t x = 2; x < XSIZE(V) - 2; x++)
2891  DIRECT_A3D_ELEM(V,z,y,x) -= lambda
2892  * DIRECT_A3D_ELEM(gradient,z,y,x);
2893 
2894  // Finish
2895  return regError;
2896 }
#define YSIZE(v)
doublereal * c
void sqrt(Image< double > &op)
static double * y
doublereal * x
double * lambda
#define XX(v)
Definition: matrix1d.h:85
#define XSIZE(v)
void write(const FileName &fn) const
#define ZSIZE(v)
double z
#define DIRECT_A3D_ELEM(v, k, i, j)
#define YY(v)
Definition: matrix1d.h:93
void initZeros(const MultidimArray< T1 > &op)
#define ZZ(v)
Definition: matrix1d.h:101

◆ varianceFilter()

void varianceFilter ( MultidimArray< double > &  I,
int  kernelSize = 10,
bool  relative = false 
)

Applays a variance filter to an image

If relative=True, the filter is normalized to the mean (coeficient of variation)

Definition at line 775 of file filters.cpp.

776 {
777  int kernelSize_2 = kernelSize/2;
778  MultidimArray<double> kernel;
779  kernel.resize(kernelSize,kernelSize);
780  kernel.setXmippOrigin();
781 
782  // std::cout << " Creating the variance matrix " << std::endl;
783  MultidimArray<double> mVar(YSIZE(I),XSIZE(I));
784  mVar.setXmippOrigin();
785  double stdKernel;
786  double avgKernel;
787  double min_val;
788  double max_val;
789  int x0;
790  int y0;
791  int xF;
792  int yF;
793 
794  // I.computeStats(avgImg, stdImg, min_im, max_im);
795 
796  for (int i=kernelSize_2; i<=(int)YSIZE(I)-kernelSize_2; i+=kernelSize_2)
797  for (int j=kernelSize_2; j<=(int)XSIZE(I)-kernelSize_2; j+=kernelSize_2)
798  {
799  x0 = j-kernelSize_2;
800  y0 = i-kernelSize_2;
801  xF = j+kernelSize_2-1;
802  yF = i+kernelSize_2-1;
803 
804  if (x0 < 0)
805  x0 = 0;
806  if (xF > XSIZE(I))
807  xF = XSIZE(I);
808  if (y0 < 0)
809  y0 = 0;
810  if (yF > YSIZE(I))
811  yF = YSIZE(I);
812 
813  I.window(kernel, y0, x0, yF, xF);
814  kernel.computeStats(avgKernel, stdKernel, min_val, max_val);
815 
816  DIRECT_A2D_ELEM(mVar, i, j) = stdKernel;
817  }
818 
819  // filtering to fill the matrices (convolving with a Gaussian)
820  FourierFilter filter;
821  filter.FilterShape = REALGAUSSIAN;
822  filter.FilterBand = LOWPASS;
823  filter.w1 = kernelSize_2;
824  filter.applyMaskSpace(mVar);
825 
826  if (relative) // normalize to the mean of the variance
827  {
828  double avgVar;
829  double stdVar;
830  double minVar;
831  double maxVar;
832  mVar.computeStats(avgVar, stdVar, minVar, maxVar);
833  mVar = mVar/avgVar;
834  }
835 
836  I = mVar;
837 
838  // filling the borders with the nearest variance value
839  // the corners only are filled once (with Ycoord)
840  for (int i=0; i<YSIZE(I); ++i)
841  for (int j=0; j<kernelSize; j++)
842  {
843  if (i<kernelSize)
844  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, kernelSize, kernelSize);
845  else if (i>YSIZE(I)-kernelSize)
846  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, YSIZE(I)-kernelSize, kernelSize);
847  else
848  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, i, kernelSize);
849  }
850  for (int i=0; i<YSIZE(I); ++i)
851  for (int j=XSIZE(I)-kernelSize; j<XSIZE(I); j++)
852  {
853  if (i<kernelSize)
854  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, kernelSize, XSIZE(I)-kernelSize);
855  else if (i>YSIZE(I)-kernelSize)
856  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, YSIZE(I)-kernelSize, XSIZE(I)-kernelSize);
857  else
858  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, i, XSIZE(I)-kernelSize);
859  }
860  for (int j=kernelSize; j<XSIZE(I)-kernelSize; ++j)
861  for (int i=0; i<kernelSize; i++)
862  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, kernelSize, j);
863  for (int j=kernelSize; j<XSIZE(I)-kernelSize; ++j)
864  for (int i=YSIZE(I)-kernelSize; i<YSIZE(I); i++)
865  DIRECT_A2D_ELEM(I, i, j) = DIRECT_A2D_ELEM(mVar, YSIZE(I)-kernelSize, j);
866 
867 }
#define YSIZE(v)
void resize(size_t Ndim, size_t Zdim, size_t Ydim, size_t Xdim, bool copy=true)
void computeStats(double &avg, double &stddev, T &minval, T &maxval) const
#define DIRECT_A2D_ELEM(v, i, j)
#define i
void window(MultidimArray< T1 > &result, int n0, int z0, int y0, int x0, int nF, int zF, int yF, int xF, T1 init_value=0) const
#define y0
#define x0
#define XSIZE(v)
#define xF
#define j
#define REALGAUSSIAN
#define yF
#define LOWPASS
void applyMaskSpace(MultidimArray< double > &v)