Dear list,
I have a curved line (of 1 px width) obtained from skeletonise. And I want to make it a segmented line of 14 key points (of known coordinates) and made of 13 segments of the same length. To finally be able to measure the angles between all these segments. Obviously I don't want to do it by hand… My first attempts were : 1. To do "Create selection" and "Area to line". But to do so I need to dilate my selection and I don't want to. Plus it makes a U-shaped line with two parts in which the angles aren't exactly the ones of the skeleton. And then I still need to extract the coordinates of the 14 points. 2. To save my binary image as "Text image". This might work but I don't know how to recover the coordinates of each 255 points and make it a line.roi file. Plus, it might be complicated because I may have several points for the same X or Y coordinate… To illustrate, i put two images : The first image is my raw image, the second one is the kind of image I'd like to obtain. Actually, I even only need the coordinates of the 13 points that are found along the original curve. So it's a bit like 1. I want all the coordinates of each white points along the curve in the raw image, 2. I want to know the length L of this line in pixels, 3. I need to divide this length by 13 (L/13=N), 4. obtain a number N and 5. gather the coordinates of the 14 points separated by this number N of points in my original image. I hope no-one asked this exact question before and that someone will be able to guide me, Thank you ! [cid:[hidden email]][cid:[hidden email]] Nicolas Brouilly, PhD Student Equipe Gieseler, "Pathologies du muscle chez C. elegans" Centre de Génétique et de Physiologie Moléculaires et Cellulaires UMR CNRS 5534 Université Claude Bernard Lyon 1 Bâtiment Gregor Mendel, 5ème étage 16, rue Raphaël Dubois F-69622 Villeurbanne Cedex [hidden email]<mailto:[hidden email]> Lab : +0033 (0)4 72 43 29 48 Cel : +0033 (0)6 42 91 53 19 |
Hi Nicholas,
looks like a task where you have to write a macro or plugin. Erode a copy of the image with 1 iteration, count=7 in the binary options, and subtract it from the original. This gives you the end points; you can get their coordinates e.g. with 'Analyze Particles' or 'Find Maxima'. Then you have to start at one of the end points of the original image and scan all its 8 neighbors (except the one visited just before) in a loop, to see where the line continues. For scanning the neighbors, you can use two arrays with the offsets to the neighboring pixels X_OFFSET = newArray( 0, 1, 1, 1, 0, -1, -1, -1 ); Y_OFFSET = newArray( -1, -1, 0, 1, 1, 1, 0, -1 ); and the loop over the neighbors would be roughly like this: for (i=0; i<8; i++) { if (firstPoint || x+X_OFFSET[i] != lastX || y+Y_OFFSET[i] != lastY) { neighbor = getPixel(x+X_OFFSET[i], y+Y_OFFSET[i]); if (neighbor == 255) { //enter new coordinates into an array } } } // if no new coordinates are found, you are done. Then you have the coordinates in a well-ordered list, and you can select part of it. Michael ________________________________________________________________ On 7 Dec 2011, at 17:02, BROUILLY NICOLAS wrote: > Dear list, > > I have a curved line (of 1 px width) obtained from skeletonise. And > I want to make it a segmented line of 14 key points (of known > coordinates) and made of 13 segments of the same length. To finally > be able to measure the angles between all these segments. > > Obviously I don't want to do it by hand… > > My first attempts were : > > 1. To do "Create selection" and "Area to line". But to do so I need > to dilate my selection and I don't want to. Plus it makes a U- > shaped line with two parts in which the angles aren't exactly the > ones of the skeleton. And then I still need to extract the > coordinates of the 14 points. > > 2. To save my binary image as "Text image". This might work but I > don't know how to recover the coordinates of each 255 points and > make it a line.roi file. Plus, it might be complicated because I > may have several points for the same X or Y coordinate… > > To illustrate, i put two images : > The first image is my raw image, the second one is the kind of > image I'd like to obtain. Actually, I even only need the > coordinates of the 13 points that are found along the original > curve. So it's a bit like 1. I want all the coordinates of each > white points along the curve in the raw image, 2. I want to know > the length L of this line in pixels, 3. I need to divide this > length by 13 (L/13=N), 4. obtain a number N and 5. gather the > coordinates of the 14 points separated by this number N of points > in my original image. > > I hope no-one asked this exact question before and that someone > will be able to guide me, > > Thank you ! > > [cid:[hidden email]][cid: > [hidden email]] > > Nicolas Brouilly, PhD Student > Equipe Gieseler, "Pathologies du muscle chez C. elegans" > > Centre de Génétique et de Physiologie Moléculaires et Cellulaires > UMR CNRS 5534 > Université Claude Bernard Lyon 1 > Bâtiment Gregor Mendel, 5ème étage > 16, rue Raphaël Dubois > F-69622 Villeurbanne Cedex > > [hidden email]<mailto:[hidden email]> > Lab : +0033 (0)4 72 43 29 48 > Cel : +0033 (0)6 42 91 53 19 > |
Hi Michael and list members,
Thank you Michael for this help ! Your idea was the fastest one I think. I followed your advice and ended with the following macro. The problem now is that I lose a point each time I have a new raw of aligned pixels (345 points of value 255 in the example image but only 283 values of X and Y coordinates in my final arrays) and I can't find from where this bug come… The example image is attached. And here is my macro : // Close everything before you start run("Close All") // Be able to print an array function printArray(a) { print(""); for (i=0; i<a.length; i++) print(i+": "+a[i]); } // Treat the image open(); name=getTitle() rename("Image1"); run("Make Binary"); run("Duplicate...", "title=[Image2]"); selectWindow("Image1"); run("Options...", "iterations=1 count=7 black edm=Overwrite do=Erode"); imageCalculator("Subtract create", "Image2","Image1"); selectWindow("Result of Image2"); // Get "Head" and "Tail" points run("Find Maxima...", "noise=10 output=[Point Selection]"); getSelectionCoordinates(x, y); HEADX=x[1]; HEADY=y[1]; TAILX=x[0]; TAILY=y[0]; // To know the length of the skeleton selectWindow("Image1"); getHistogram(values, counts, 256); INFO=newArray(counts[255]); LENG=lengthOf(INFO); print(LENG) COORDX=newArray(LENG); COORDY=newArray(LENG); // To scan the neighboors selectWindow("Image1"); X_OFFSET = newArray( 0, 1, 1, 1, 0, -1, -1, -1 ); Y_OFFSET = newArray( -1, -1, 0, 1, 1, 1, 0, -1 ); for (j=0; j<LENG; j++) { for (i=0; i<8; i++) { if (HEADX+X_OFFSET[i] != TAILX || HEADY+Y_OFFSET[i] != TAILY) { neighbor = getPixel(HEADX+X_OFFSET[i], HEADY+Y_OFFSET[i]); if (neighbor == 255) { COORDX[j]=HEADX; COORDY[j]=HEADY; //print(HEADY+Y_OFFSET[i]); setPixel(HEADX, HEADY, 100); HEADX=HEADX+X_OFFSET[i]; HEADY=HEADY+Y_OFFSET[i]; } } } } printArray(COORDX); printArray(COORDY); Thank you for any good advice (again). Nico |
Hi Nico,
you after finding a new point, you have to quit (break) the inner loop over i. Otherwise, it continues to search for neighbors from the new position, and if the direction changes it may find a neighbor of the neighbor. Then it will write two points to the same array position, but, of course, only one is kept. if (neighbor == 255) { COORDX[j]=HEADX; COORDY[j]=HEADY; setPixel(HEADX, HEADY, 100); HEADX=HEADX+X_OFFSET[i]; HEADY=HEADY+Y_OFFSET[i]; i=8; // break (quit the loop) } Michael ___________________________________________________________________ On Sun, December 11, 2011 17:52, BROUILLY NICOLAS wrote: > Hi Michael and list members, > > Thank you Michael for this help ! Your idea was the fastest one I think. > > I followed your advice and ended with the following macro. The problem now > is that I lose a point each time I have a new raw of aligned pixels (345 > points of value 255 in the example image but only 283 values of X and Y > coordinates in my final arrays) and I can't find from where this bug come > > The example image is attached. > > And here is my macro : > > // Close everything before you start > > run("Close All") > > // Be able to print an array > > function printArray(a) { > print(""); > for (i=0; i<a.length; i++) > print(i+": "+a[i]); > } > > // Treat the image > > open(); > name=getTitle() > rename("Image1"); > run("Make Binary"); > run("Duplicate...", "title=[Image2]"); > selectWindow("Image1"); > run("Options...", "iterations=1 count=7 black edm=Overwrite do=Erode"); > imageCalculator("Subtract create", "Image2","Image1"); > selectWindow("Result of Image2"); > > // Get "Head" and "Tail" points > > run("Find Maxima...", "noise=10 output=[Point Selection]"); > getSelectionCoordinates(x, y); > > HEADX=x[1]; > HEADY=y[1]; > TAILX=x[0]; > TAILY=y[0]; > > // To know the length of the skeleton > > selectWindow("Image1"); > getHistogram(values, counts, 256); > INFO=newArray(counts[255]); > LENG=lengthOf(INFO); > print(LENG) > COORDX=newArray(LENG); > COORDY=newArray(LENG); > > // To scan the neighboors > > selectWindow("Image1"); > > X_OFFSET = newArray( 0, 1, 1, 1, 0, -1, -1, -1 ); > Y_OFFSET = newArray( -1, -1, 0, 1, 1, 1, 0, -1 ); > > for (j=0; j<LENG; j++) { > > for (i=0; i<8; i++) { > > if (HEADX+X_OFFSET[i] != TAILX || HEADY+Y_OFFSET[i] != TAILY) > { > neighbor = getPixel(HEADX+X_OFFSET[i], HEADY+Y_OFFSET[i]); > if (neighbor == 255) > { > COORDX[j]=HEADX; > COORDY[j]=HEADY; > //print(HEADY+Y_OFFSET[i]); > setPixel(HEADX, HEADY, 100); > HEADX=HEADX+X_OFFSET[i]; > HEADY=HEADY+Y_OFFSET[i]; > > } > } > } > > } > > printArray(COORDX); > printArray(COORDY); > > > Thank you for any good advice (again). > > Nico > > |
Free forum by Nabble | Edit this page |