Xmipp  v3.23.11-Nereus
Mathematical morphology
Collaboration diagram for Mathematical morphology:

Morphology 2D processes

The neighbourhood must be 4 or 8.

Count is the number of pixels meeting the condition so that the operation is performed, by default, 0. Ie, if more than 0 pixels meet the condition then the corresponding operation is applied.

Example of use:

maskDilated.initZeros(mask);
dilate2D(mask,maskDilated,8,0,patchSize);

Size is the size of the structuring element (box).

The output image must be already resized to the desired shape

void dilate2D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void erode2D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void closing2D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void opening2D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void border (const MultidimArray< double > &img, MultidimArray< double > &border)
 
void simplify_border (const MultidimArray< double > &border, MultidimArray< double > &simplified_border)
 
void random_convex_hull (const MultidimArray< double > &img, MultidimArray< double > &hull, long N=100)
 

Morphology 3D processes

The neighbourhood must be 6, 18 or 26.

Count is the number of voxels meeting the condition so that the operation is performed, by default, 0. Ie, if more than 0 voxels meet the condition then the corresponding operation is applied.

Size is the size of the structuring element (box).

The output image must be already resized to the desired shape

void dilate3D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void erode3D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void closing3D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void opening3D (const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
 
void dilate3D (const MultidimArray< double > &in, const MultidimArray< double > &structuringElement, MultidimArray< double > &out)
 
void erode3D (const MultidimArray< double > &in, const MultidimArray< double > &structuringElement, MultidimArray< double > &out)
 
void sharpening (const MultidimArray< double > &in, double width, double strength, MultidimArray< double > &out)
 

Detailed Description

Function Documentation

◆ border()

void border ( const MultidimArray< double > &  img,
MultidimArray< double > &  border 
)

Border of a binary image. The border is computed as the subtraction of an image and its dilation.

Definition at line 167 of file morphology.cpp.

168 {
169  /*
170  border.initZeros(img);
171  erode2D(img,border,8,0,1);
172  FOR_ALL_ELEMENTS_IN_ARRAY2D(border)
173  border(i,j)=img(i,j)-border(i,j);
174  */
175  border.initZeros(img);
176  for (int i = STARTINGY(border) + 1; i <= FINISHINGY(border) - 1; i++)
177  for (int j = STARTINGX(border) + 1; j <= FINISHINGX(border) - 1; j++)
178  if (img(i, j))
179  {
180  // Number of 4 neighbours
181  int N4 = 0;
182  if (img(i + 1, j))
183  N4++;
184  if (img(i - 1, j))
185  N4++;
186  if (img(i, j + 1))
187  N4++;
188  if (img(i, j - 1))
189  N4++;
190  if (N4 != 4)
191  border(i, j) = 1;
192  }
193 }
#define FINISHINGX(v)
void border(const MultidimArray< double > &img, MultidimArray< double > &border)
Definition: morphology.cpp:167
#define STARTINGX(v)
#define i
#define STARTINGY(v)
#define j
#define FINISHINGY(v)
void initZeros(const MultidimArray< T1 > &op)

◆ closing2D()

void closing2D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Closing=Dilation+Erosion

Definition at line 130 of file morphology.cpp.

132 {
134  int i;
135  tmp = in;
136  for (i = 0;i < size;i++)
137  { //dilate
138  dilate2D_step(tmp, out, neig, count);
139  tmp = out;
140  }
141  for (i = 0;i < size;i++)
142  { // erode
143  erode2D_step(tmp, out, neig, count);
144  tmp = out;
145  }
146 }
void dilate2D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:32
#define i
void erode2D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:67
int in

◆ closing3D()

void closing3D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Binary Closing=Dilation+Erosion

Definition at line 422 of file morphology.cpp.

424 {
426  int i;
427  tmp = in;
428  for (i = 0;i < size;i++)
429  { //dilate
430  dilate3D_step(tmp, out, neig, count);
431  tmp = out;
432  }
433  for (i = 0;i < size;i++)
434  { // erode
435  erode3D_step(tmp, out, neig, count);
436  tmp = out;
437  }
438 }
#define i
void dilate3D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:290
int in
void erode3D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:339

◆ dilate2D()

void dilate2D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Dilate. See the group documentation for the parameter meanings

Definition at line 103 of file morphology.cpp.

105 {
107  int i;
108  tmp = in;
109  for (i = 0;i < size;i++)
110  {
111  dilate2D_step(tmp, out, neig, count);
112  tmp = out;
113  }
114 }
void dilate2D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:32
#define i
int in

◆ dilate3D() [1/2]

void dilate3D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Binary Dilate. See the group documentation for the parameter meanings

Definition at line 394 of file morphology.cpp.

396 {
398  int i;
399  tmp = in;
400  for (i = 0;i < size;i++)
401  {
402  dilate3D_step(tmp, out, neig, count);
403  tmp = out;
404  }
405 }
#define i
void dilate3D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:290
int in

◆ dilate3D() [2/2]

void dilate3D ( const MultidimArray< double > &  in,
const MultidimArray< double > &  structuringElement,
MultidimArray< double > &  out 
)

Gray dilation. The structuring element must be centered at 0.

Definition at line 459 of file morphology.cpp.

462 {
463  out.initZeros(in);
464  double maxval=in.computeMax();
465  for (size_t kk=0; kk<ZSIZE(out); kk++)
466  for (size_t ii=0; ii<YSIZE(out); ii++)
467  for (size_t jj=0; jj<XSIZE(out); jj++)
468  {
469  double maxLocal=DIRECT_A3D_ELEM(in,kk,ii,jj)+
470  A3D_ELEM(structuringElement,0,0,0);
471  int k0=XMIPP_MAX(0,kk+STARTINGZ(structuringElement))-kk;
472  int kF=XMIPP_MIN(ZSIZE(out)-1,kk+FINISHINGZ(structuringElement))-kk;
473  int i0=XMIPP_MAX(0,ii+STARTINGY(structuringElement))-ii;
474  int iF=XMIPP_MIN(YSIZE(out)-1,ii+FINISHINGY(structuringElement))-ii;
475  int j0=XMIPP_MAX(0,jj+STARTINGX(structuringElement))-jj;
476  int jF=XMIPP_MIN(XSIZE(out)-1,jj+FINISHINGX(structuringElement))-jj;
477  for (int k=k0; k<=kF; k++)
478  for (int i=i0; i<=iF; i++)
479  for (int j=j0; j<=jF; j++)
480  {
481  double val=DIRECT_A3D_ELEM(in,kk+k,ii+i,jj+j)+
482  A3D_ELEM(structuringElement,k,i,j);
483  maxLocal=XMIPP_MAX(maxLocal,val);
484  }
485  maxLocal=XMIPP_MIN(maxLocal,maxval);
486  DIRECT_A3D_ELEM(out,kk,ii,jj)=maxLocal;
487  }
488 }
#define YSIZE(v)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
#define FINISHINGX(v)
#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
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
#define XSIZE(v)
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
#define FINISHINGY(v)
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)
T computeMax() const

◆ erode2D()

void erode2D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Erode. See the group documentation for the parameter meanings

Definition at line 116 of file morphology.cpp.

118 {
120  int i;
121  tmp = in;
122  for (i = 0;i < size;i++)
123  {
124  erode2D_step(tmp, out, neig, count);
125  tmp = out;
126  }
127 }
#define i
void erode2D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:67
int in

◆ erode3D() [1/2]

void erode3D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Binary Erode. See the group documentation for the parameter meanings

Definition at line 407 of file morphology.cpp.

409 {
411  int i;
412  tmp = in;
413  for (i = 0;i < size;i++)
414  {
415  erode3D_step(tmp, out, neig, count);
416  tmp = out;
417  }
418 
419 }
#define i
int in
void erode3D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:339

◆ erode3D() [2/2]

void erode3D ( const MultidimArray< double > &  in,
const MultidimArray< double > &  structuringElement,
MultidimArray< double > &  out 
)

Gray erosion. The structuring element must be centered at 0.

Definition at line 490 of file morphology.cpp.

493 {
494  out.initZeros(in);
495  double minval=in.computeMin();
496  for (size_t kk=0; kk<ZSIZE(out); kk++)
497  for (size_t ii=0; ii<YSIZE(out); ii++)
498  for (size_t jj=0; jj<XSIZE(out); jj++)
499  {
500  double minLocal=DIRECT_A3D_ELEM(in,kk,ii,jj)-
501  A3D_ELEM(structuringElement,0,0,0);
502  int k0=XMIPP_MAX(0,kk+STARTINGZ(structuringElement))-kk;
503  int kF=XMIPP_MIN(ZSIZE(out)-1,kk+FINISHINGZ(structuringElement))-kk;
504  int i0=XMIPP_MAX(0,ii+STARTINGY(structuringElement))-ii;
505  int iF=XMIPP_MIN(YSIZE(out)-1,ii+FINISHINGY(structuringElement))-ii;
506  int j0=XMIPP_MAX(0,jj+STARTINGX(structuringElement))-jj;
507  int jF=XMIPP_MIN(XSIZE(out)-1,jj+FINISHINGX(structuringElement))-jj;
508  for (int k=k0; k<=kF; k++)
509  for (int i=i0; i<=iF; i++)
510  for (int j=j0; j<=jF; j++)
511  {
512  double val=DIRECT_A3D_ELEM(in,kk+k,ii+i,jj+j)-
513  A3D_ELEM(structuringElement,k,i,j);
514  minLocal=XMIPP_MIN(minLocal,val);
515  }
516  minLocal=XMIPP_MAX(minLocal,minval);
517  DIRECT_A3D_ELEM(out,kk,ii,jj)=minLocal;
518  }
519 }
#define YSIZE(v)
#define XMIPP_MAX(x, y)
Definition: xmipp_macros.h:193
#define FINISHINGX(v)
#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
#define STARTINGY(v)
#define A3D_ELEM(V, k, i, j)
T computeMin() const
#define XSIZE(v)
#define ZSIZE(v)
#define DIRECT_A3D_ELEM(v, k, i, j)
#define XMIPP_MIN(x, y)
Definition: xmipp_macros.h:181
#define j
#define FINISHINGY(v)
void initZeros(const MultidimArray< T1 > &op)
#define STARTINGZ(v)

◆ opening2D()

void opening2D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Opening=Erosion+Dilation

Definition at line 148 of file morphology.cpp.

150 {
152  int i;
153  tmp = in;
154  for (i = 0;i < size;i++)
155  { // erode
156  erode2D_step(tmp, out, neig, count);
157  tmp = out;
158  }
159  for (i = 0;i < size;i++)
160  { //dilate
161  dilate2D_step(tmp, out, neig, count);
162  tmp = out;
163  }
164 }
void dilate2D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:32
#define i
void erode2D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:67
int in

◆ opening3D()

void opening3D ( const MultidimArray< double > &  in,
MultidimArray< double > &  out,
int  neig,
int  count,
int  size 
)

Binary Opening=Erosion+Dilation

Definition at line 440 of file morphology.cpp.

442 {
444  int i;
445  tmp=in;
446  for (i = 0;i < size;i++)
447  { // erode
448  erode3D_step(tmp, out, neig, count);
449  tmp = out;
450  }
451  for (i = 0;i < size;i++)
452  { //dilate
453  dilate3D_step(tmp, out, neig, count);
454  tmp = out;
455  }
456 }
#define i
void dilate3D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:290
int in
void erode3D_step(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count)
Definition: morphology.cpp:339

◆ random_convex_hull()

void random_convex_hull ( const MultidimArray< double > &  img,
MultidimArray< double > &  hull,
long  N = 100 
)

Random Convex hull. This routine takes a random number (N) of triangles within the image and fill these triangles. The effect is like that of creating the convex hull of a binary image.

Definition at line 241 of file morphology.cpp.

243 {
244  hull = img;
245 
246  std::vector<int> full_tx;
247  std::vector<int> full_ty;
248  // Build the list of points
250  if (img(i, j) > 0)
251  {
252  full_tx.push_back(j);
253  full_ty.push_back(i);
254  }
255 
256  long n = 0;
257  int idx_max = full_tx.size() - 1;
258  if (idx_max < 2)
259  return;
260  while (n++ < N)
261  {
262  // Generate 3 random points
263  int i = ROUND(rnd_unif(0, idx_max));
264  int j = ROUND(rnd_unif(0, idx_max));
265  int k = ROUND(rnd_unif(0, idx_max));
266 
267  // Get their positions
268  int tx[3];
269  int ty[3];
270  tx[0] = full_tx[i];
271  ty[0] = full_ty[i];
272  tx[1] = full_tx[j];
273  ty[1] = full_ty[j];
274  tx[2] = full_tx[k];
275  ty[2] = full_ty[k];
276 
277  // Fill the triangle
278  fillTriangle(hull, tx, ty, 1);
279  }
280  /*
281  MultidimArray<double> aux;
282  aux.initZeros(hull);
283  closing2D(hull,aux,8,0,1);
284  hull=aux;
285  */
286  fillBinaryObject(hull);
287 }
#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)
double rnd_unif()
#define ROUND(x)
Definition: xmipp_macros.h:210
#define j
void fillBinaryObject(MultidimArray< double > &I, int neighbourhood)
Definition: filters.cpp:758
void fillTriangle(MultidimArray< double > &img, int *tx, int *ty, double color)
Definition: filters.cpp:3012
int * n

◆ sharpening()

void sharpening ( const MultidimArray< double > &  in,
double  width,
double  strength,
MultidimArray< double > &  out 
)

Sharpening. Width (radius in pixels), strength (as a percentange of the input range).

Implemented according to JGM Schavemaker, MJT Reinders, JJ Gerbrands, E Backer. Image sharpening by morphological filtering. Pattern Recognition 33: 997-1012 (2000).

Definition at line 522 of file morphology.cpp.

524 {
525  // Build the quadratic kernel
526  auto diameter=(int)(2*width+1);
527  MultidimArray<double> kernel(diameter,diameter,diameter);
528  kernel.setXmippOrigin();
529 
530  double width2=width*width;
531  double minval=0.;
532  double maxval=0.;
533  in.computeDoubleMinMax(minval,maxval);
534  double c=minval+(maxval-minval)*strength/100;
535  double a=(minval-c)/width2;
536 
538  {
539  double r2=k*k+i*i+j*j;
540  A3D_ELEM(kernel,k,i,j)=a*r2+c;
541  }
542 
543  // Create the dilated and eroded versions
544  MultidimArray<double> dilated;
545  MultidimArray<double> eroded;
546  dilate3D(in,kernel,dilated);
547  erode3D(in,kernel,eroded);
548 #ifdef DEBUG
549  Image<double> save;
550  save()=dilated; save.write("PPPdilated.vol");
551  save()=eroded; save.write("PPPeroded.vol");
552 #endif
553 
554  // Sharpen
555  out=in;
556  double eps=(maxval-minval)*0.01;
558  {
559  double threshold=0.5*(A3D_ELEM(dilated,k,i,j)+A3D_ELEM(eroded,k,i,j));
560  if (A3D_ELEM(in,k,i,j)>threshold+eps) A3D_ELEM(out,k,i,j)=A3D_ELEM(dilated,k,i,j);
561  else if (A3D_ELEM(in,k,i,j)<threshold-eps) A3D_ELEM(out,k,i,j)=A3D_ELEM(eroded,k,i,j);
562  }
563 }
void erode3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:407
doublereal * c
void write(const FileName &name="", size_t select_img=ALL_IMAGES, bool isStack=false, int mode=WRITE_OVERWRITE, CastWriteMode castMode=CW_CAST, int _swapWrite=0)
cmache_1 eps
#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 threshold(double *phi, unsigned long nvox, double limit)
Definition: lib_vwk.cpp:524
#define A3D_ELEM(V, k, i, j)
#define FOR_ALL_ELEMENTS_IN_ARRAY3D(V)
int in
void computeDoubleMinMax(double &minval, double &maxval) const
#define j
void dilate3D(const MultidimArray< double > &in, MultidimArray< double > &out, int neig, int count, int size)
Definition: morphology.cpp:394
float r2
doublereal * a

◆ simplify_border()

void simplify_border ( const MultidimArray< double > &  border,
MultidimArray< double > &  simplified_border 
)

Simplify border. The border is simplified by removing all points having more than 2 neighbours.

Definition at line 196 of file morphology.cpp.

198 {
200  aux.initZeros(border);
201  for (int i = STARTINGY(border) + 1; i <= FINISHINGY(border) - 1; i++)
202  for (int j = STARTINGX(border) + 1; j <= FINISHINGX(border) - 1; j++)
203  if (border(i, j))
204  {
205  // Number of 4 neighbours
206  int N4 = 0;
207  if (border(i + 1, j))
208  N4++;
209  if (border(i - 1, j))
210  N4++;
211  if (border(i, j + 1))
212  N4++;
213  if (border(i, j - 1))
214  N4++;
215  if (N4 <= 2)
216  aux(i, j) = 1;
217  }
218 
219  // Again removing all those without any 4 neighbour
220  simplified_border.initZeros(aux);
221  for (int i = STARTINGY(border) + 1; i <= FINISHINGY(border) - 1; i++)
222  for (int j = STARTINGX(border) + 1; j <= FINISHINGX(border) - 1; j++)
223  if (aux(i, j))
224  {
225  // Number of 4 neighbours
226  int N4 = 0;
227  if (aux(i + 1, j))
228  N4++;
229  if (aux(i - 1, j))
230  N4++;
231  if (aux(i, j + 1))
232  N4++;
233  if (aux(i, j - 1))
234  N4++;
235  if (N4 >= 1)
236  simplified_border(i, j) = 1;
237  }
238 }
#define FINISHINGX(v)
void border(const MultidimArray< double > &img, MultidimArray< double > &border)
Definition: morphology.cpp:167
#define STARTINGX(v)
#define i
#define STARTINGY(v)
#define j
#define FINISHINGY(v)
void initZeros(const MultidimArray< T1 > &op)