Smoothing a ROI

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Smoothing a ROI

Gabriel Landini
Hi,
I am trying to smooth an ROI by doing a running a series of average of size 3
on the coordinates of the ROI:

//------------8<----------------------
getSelectionCoordinates(x, y);
run("Select None");
makeSelection("polygon", x, y);

l=x.length;
print(l);
nx=newArray(l);
ny=newArray(l);

for (i=1;i<l-1;i++){
 nx[i]=round(((x[i-1]+x[i]+x[i+1])/3)+random-0.5);
 ny[i]=round(((y[i-1]+y[i]+y[i+1])/3)+random-0.5);
}

nx[0]=round(((x[l-1]+x[0]+x[1])/3)+random-0.5);
ny[0]=round(((y[l-1]+y[0]+y[1])/3)+random-0.5);

nx[l-1]=nx[0];
ny[l-1]=ny[0];

run("Select None");
makeSelection("polygon", nx, ny);
//------------8<----------------------

Although this kind-of-works to show the idea, the number of ROI coordinates
remains constant while the ROI slowly contracts, which means that there must
be several repeated ROI coordinates (which cannot be seen as they overlap).  
So this has the disadvantage that after several passes some coordinates are
made of many superimposed points that do not get smoothed at the rate one
would expect.

Is there any way of getting rid of the repeated ROI coordinates other than
creating a new array which is populated with only the unique coordinates?

I also tried a version of ROI closing, but this is not exactly what I want:
for (i=1;i<10;i++) {
 run("Enlarge...", "enlarge="+i);
 run("Enlarge...", "enlarge=-"+i);
}

Thanks for any pointers

Cheers

Gabriel
Reply | Threaded
Open this post in threaded view
|

Re: Smoothing a ROI

dscho
Hi,

On Sun, 13 Feb 2011, Gabriel Landini wrote:

> I am trying to smooth an ROI by doing a running a series of average of
> size 3 on the coordinates of the ROI:

It might be easier to smooth the mask, apply an automatic threshold, and
create a new selection.

Ciao,
Dscho
Reply | Threaded
Open this post in threaded view
|

Re: Smoothing a ROI

Gabriel Landini
Thanks Dscho for the suggestion.
I ended up thinning the ROI coordinates. Maybe this is useful to somebody
else, so below is the macro.
If somebody spots any problems or improves it please let me know.

Cheers
Gabriel

//---------------------8<-------------------
// smooth_ROI.txt
// G. Landini at bham. ac. uk
// 13/2/2011
// Performs a running average of size 3 on a closed ROI to smooth it

sel=selectionType();
if (sel <2 ||sel>4)
     exit("Only freehand closed ROIs are supported.");

getSelectionCoordinates(x, y);
run("Select None");
makeSelection("polygon", x, y);

l=x.length;
print(l);
nx=newArray(l);
ny=newArray(l);

for (i=1;i<l-1;i++){
 nx[i]=round(((x[i-1]+x[i]+x[i+1])/3)+random-0.5);
 ny[i]=round(((y[i-1]+y[i]+y[i+1])/3)+random-0.5);
}

// l-2 because last coordinate==first
nx[0]=round(((x[l-2]+x[0]+x[1])/3)+random-0.5);
ny[0]=round(((y[l-2]+y[0]+y[1])/3)+random-0.5);
//last
nx[l-1]=nx[0];
ny[l-1]=ny[0];

run("Select None");

// count how many are overlapping
tot=0;
for (i=1;i<l;i++){
  if ( (nx[i]== nx[i-1]) && (ny[i] == ny[i-1] ) )
    tot++;
}

if (tot>0) {
   nex=newArray(l-tot);
   ney=newArray(l-tot);
   nex[0]=nx[0];
   ney[0]=ny[0];

   st=0;
   for (j=1;j<l;j++){
      if ((nx[j]  != nx[j-1]) || (ny[j] != ny[j-1]) )  {
        st++;
        nex[st]=nx[j];
        ney[st]=ny[j];
      }
   }
   nex[l-tot-1]=nex[0];
   ney[l-tot-1]=ney[0];
   makeSelection("polygon", nex, ney);
}
else
   makeSelection("polygon", nx, ny);
 
//---------------------8<-------------------
Reply | Threaded
Open this post in threaded view
|

Re: Smoothing a ROI

Giuseppe Lucarelli
Hi Gabriel,

I had a play with your ROI smoothing macro and it works well for me.

However, I don't understand what the code is doing in the second part of the macro when you check for overlapping coordinates.
Could please explain.

I also made a version where the average is out of the 5 neighboring points of the selection. This also works but I didn't include the code that checks for overlapping coordinates.

Thanks,

Giuseppe Lucarelli

<quote author="Gabriel Landini">
Thanks Dscho for the suggestion.
I ended up thinning the ROI coordinates. Maybe this is useful to somebody
else, so below is the macro.
If somebody spots any problems or improves it please let me know.

Cheers
Gabriel

//---------------------8<-------------------
// smooth_ROI.txt
// G. Landini at bham. ac. uk
// 13/2/2011
// Performs a running average of size 3 on a closed ROI to smooth it

sel=selectionType();
if (sel <2 ||sel>4)
     exit("Only freehand closed ROIs are supported.");

getSelectionCoordinates(x, y);
run("Select None");
makeSelection("polygon", x, y);

l=x.length;
print(l);
nx=newArray(l);
ny=newArray(l);

for (i=1;i<l-1;i++){
 nx[i]=round(((x[i-1]+x[i]+x[i+1])/3)+random-0.5);
 ny[i]=round(((y[i-1]+y[i]+y[i+1])/3)+random-0.5);
}

// l-2 because last coordinate==first
nx[0]=round(((x[l-2]+x[0]+x[1])/3)+random-0.5);
ny[0]=round(((y[l-2]+y[0]+y[1])/3)+random-0.5);
//last
nx[l-1]=nx[0];
ny[l-1]=ny[0];

run("Select None");

// count how many are overlapping
tot=0;
for (i=1;i<l;i++){
  if ( (nx[i]== nx[i-1]) && (ny[i] == ny[i-1] ) )
    tot++;
}

if (tot>0) {
   nex=newArray(l-tot);
   ney=newArray(l-tot);
   nex[0]=nx[0];
   ney[0]=ny[0];

   st=0;
   for (j=1;j<l;j++){
      if ((nx[j]  != nx[j-1]) || (ny[j] != ny[j-1]) )  {
        st++;
        nex[st]=nx[j];
        ney[st]=ny[j];
      }
   }
   nex[l-tot-1]=nex[0];
   ney[l-tot-1]=ney[0];
   makeSelection("polygon", nex, ney);
}
else
   makeSelection("polygon", nx, ny);
 
//---------------------8<-------------------
</quote>
Reply | Threaded
Open this post in threaded view
|

Re: Smoothing a ROI

Gabriel Landini
On Monday 08 Sep 2014 18:41:17 giuseppe3 wrote:
> I had a play with your ROI smoothing macro and it works well for me.
>
> However, I don't understand what the code is doing in the second part of the
> macro when you check for overlapping coordinates.
> Could please explain.

Hi,
It gets rid of overlapping coordinates of the ROI that do not contribute to
the actual shown shape. If you run consecutively the macro several times you
end up with lots of repeated ROI points in the ROI chain that do not make a
difference to the ROI that you see. The code gets rid of those.
If there are no overlapping points it uses the original smoothed chain, if
there are, it uses the thinned chain.

Regards

Gabriel

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Smoothing a ROI

Giuseppe Lucarelli
Thank you so much Gabriel!

On 9 September 2014 20:56, Gabriel Landini [via ImageJ] <[hidden email]> wrote:
On Monday 08 Sep 2014 18:41:17 giuseppe3 wrote:
> I had a play with your ROI smoothing macro and it works well for me.
>
> However, I don't understand what the code is doing in the second part of the
> macro when you check for overlapping coordinates.
> Could please explain.

Hi,
It gets rid of overlapping coordinates of the ROI that do not contribute to
the actual shown shape. If you run consecutively the macro several times you
end up with lots of repeated ROI points in the ROI chain that do not make a
difference to the ROI that you see. The code gets rid of those.
If there are no overlapping points it uses the original smoothed chain, if
there are, it uses the thinned chain.

Regards

Gabriel

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html



If you reply to this email, your message will be added to the discussion below:
http://imagej.1557.x6.nabble.com/Smoothing-a-ROI-tp3685699p5009553.html
To unsubscribe from Smoothing a ROI, click here.
NAML



--
Giuseppe Lucarelli
Biochemistry PhD student
Prescott/Devenish Lab, Bld 13 D224a
PH  990 53785