Dear all,
There are several ways to get the particle size. But I want to try "intersect line method". I know how to get the "Plot Profile". However, I do not know how to get the particle size automatically. Imaging I have many images, it will be convenient to apply Macros. Is there available Macros for use? I failed to find one. Could anyone help me? I attached one example image. Thanks! -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html intersect line.tif (344K) Download Attachment |
Good day!
Neither from here, nor from the IJ-forum you've received satisfying solutions and I guess this is due to the fact that your seemingly simple problem in fact is rather complicated. I've spent several hours but wasn't successful either. Here are some hints: 1. "intersect line method" (successive image profiles) I doubt what you've written elsewhere, namely that one can distinguish signal and background by *simply* analyzing profiles. The reason is that the fluctuations are too large. 2. For the provided sample image I was able to compute a reasonable binary contour image (see attachment). Here is the ImageJ-macro code: // imagej-macro "meanderContours" (Herbie G., 26. Feb. 2019) requires( "1.52k" ); setBackgroundColor(0, 0, 0); setOption("BlackBackground", true); img=getTitle(); setBatchMode(true); run("Duplicate...", "title=copy"); run("Median...", "radius=2"); run("Bandpass Filter...", "filter_large=3 filter_small=0 suppress=None tolerance=5"); setAutoThreshold("RenyiEntropy dark"); run("Convert to Mask"); run("Analyze Particles...", "size=0-50 pixel add"); n=roiManager("count"); a=Array.getSequence(n) ; roiManager("select", a ); roiManager("combine"); roiManager("add"); roiManager("Delete"); roiManager("Select", 0); run("Clear", "slice"); close("ROI Manager"); run("Remove Overlay"); run("Select None"); run("Close-"); run("Skeletonize"); setBatchMode(false); makeRectangle(3,3,668,376); run("Crop"); run("Select None"); exit(); // imagej-macro "meanderContours" (Herbie G., 26. Feb. 2019) I have no idea how this approach generalized to other images of this kind! 3. To find the area of the signal or of the background from the binary contour image turned out being really complicated and I haven't found a convincing approach yet. Here is an ImageJ-macro code that may give you an idea of how to start but it doesn't do the complete job (see attached result image): // imagej-macro "fillMeander" (Herbie G., 27. Feb. 2019) requires( "1.52k" ); setForegroundColor(255, 255, 255); makeRectangle(0,0,668,1); analyzeProfile(); exit(); function analyzeProfile() { p=getProfile(); p=Array.concat(Array.concat(0,p), 0); n=p.length; a=newArray(n*0.5); idx=1; for ( i=0; i<n; i++ ) { if (p[i]>0) { if (p[i-1]<255 || p[i+1]<255) {a[idx]=i-1; idx++;} else setPixel(i-1, 0, 0); // care fore line breaks (single code line here) } } a=Array.trim(a, idx+1); a[idx]=getWidth()-1; a[0]=0; floodFill(0.5*a[0], 0); odd=false; for ( i=0; i<idx; i++ ) { x=0.5*(a[i]+a[i+1]); val=getPixel(x, 0); if (odd) { if (val<255) {floodFill(x, 0); } odd=false; } else { if (val<255) odd=true; } } } // imagej-macro "fillMeander" (Herbie G., 27. Feb. 2019) Good luck Herbie :::::::::::::::::::::::::::::::::::::::: Am 24.02.19 um 15:03 schrieb Steven Liu: > Dear all, > There are several ways to get the particle size. But I want to try "intersect line method". I know how to get the "Plot Profile". However, I do not know how to get the particle size automatically. Imaging I have many images, it will be convenient to apply Macros. > Is there available Macros for use? I failed to find one. > Could anyone help me? > I attached one example image. > Thanks! > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Good day Jeremy,
I think the OP was quite clear in one of his earlier posts here or on the forum. His problem is clearly 2D and if the meander-object had more even values and significant contrast one could work with profiles of lines. However, both conditions are not fulfilled. Of course the number of intersections alone is insufficient... Regards Herbie :::::::::::::::::::::::::::::::::::::::::: Am 02.03.19 um 17:39 schrieb Jeremy Adler: > A more basic question is does the intersect line method actually produce > a particle size estimate. > > > Consider two particles with the same area, one with a smooth edge and > the second with a crenellated edge. The areas are the same but the > number of intersections will clearly differ. By size we normally mean > area, which clearly cannot be provided by the number of intersections. > > > If a single particle is present then a perimeter estimate is possible > but when more than one particle is present the method contains no > mechanism for counting the number of particles and cannot produce > particle size. > > > Finally most particles are not 2 dimensional and a single 2D image > cannot be used to determine size (volume) or surface area. > > > So back the basic question - what measurement is wanted. > > > Jeremy Adler > > Uppsala U > > > > ------------------------------------------------------------------------ > *From:* ImageJ Interest Group <[hidden email]> on behalf of Herbie > <[hidden email]> > *Sent:* 02 March 2019 15:47 > *To:* [hidden email] > *Subject:* Re: particle size by using intersect line? > Good day! > > Neither from here, nor from the IJ-forum you've received satisfying > solutions and I guess this is due to the fact that your seemingly simple > problem in fact is rather complicated. > > I've spent several hours but wasn't successful either. > > Here are some hints: > > 1. "intersect line method" (successive image profiles) > I doubt what you've written elsewhere, namely that one can distinguish > signal and background by *simply* analyzing profiles. The reason is that > the fluctuations are too large. > > 2. For the provided sample image I was able to compute a reasonable > binary contour image (see attachment). Here is the ImageJ-macro code: > > // imagej-macro "meanderContours" (Herbie G., 26. Feb. 2019) > requires( "1.52k" ); > setBackgroundColor(0, 0, 0); > setOption("BlackBackground", true); > img=getTitle(); > setBatchMode(true); > run("Duplicate...", "title=copy"); > run("Median...", "radius=2"); > run("Bandpass Filter...", "filter_large=3 filter_small=0 suppress=None > tolerance=5"); > setAutoThreshold("RenyiEntropy dark"); > run("Convert to Mask"); > run("Analyze Particles...", "size=0-50 pixel add"); > n=roiManager("count"); > a=Array.getSequence(n) ; > roiManager("select", a ); > roiManager("combine"); > roiManager("add"); > roiManager("Delete"); > roiManager("Select", 0); > run("Clear", "slice"); > close("ROI Manager"); > run("Remove Overlay"); > run("Select None"); > run("Close-"); > run("Skeletonize"); > setBatchMode(false); > makeRectangle(3,3,668,376); > run("Crop"); > run("Select None"); > exit(); > // imagej-macro "meanderContours" (Herbie G., 26. Feb. 2019) > > I have no idea how this approach generalized to other images of this kind! > > 3. To find the area of the signal or of the background from the binary > contour image turned out being really complicated and I haven't found a > convincing approach yet. Here is an ImageJ-macro code that may give you > an idea of how to start but it doesn't do the complete job (see attached > result image): > > // imagej-macro "fillMeander" (Herbie G., 27. Feb. 2019) > requires( "1.52k" ); > setForegroundColor(255, 255, 255); > makeRectangle(0,0,668,1); > analyzeProfile(); > exit(); > function analyzeProfile() { > p=getProfile(); > p=Array.concat(Array.concat(0,p), 0); > n=p.length; > a=newArray(n*0.5); > idx=1; > for ( i=0; i<n; i++ ) { > if (p[i]>0) { > if (p[i-1]<255 || p[i+1]<255) {a[idx]=i-1; idx++;} else > setPixel(i-1, 0, 0); // care fore line breaks (single code line here) > } > } > a=Array.trim(a, idx+1); > a[idx]=getWidth()-1; > a[0]=0; > floodFill(0.5*a[0], 0); > odd=false; > for ( i=0; i<idx; i++ ) { > x=0.5*(a[i]+a[i+1]); > val=getPixel(x, 0); > if (odd) { > if (val<255) {floodFill(x, 0); } > odd=false; > } else { > if (val<255) odd=true; > } > } > } > // imagej-macro "fillMeander" (Herbie G., 27. Feb. 2019) > > Good luck > > Herbie > > :::::::::::::::::::::::::::::::::::::::: > Am 24.02.19 um 15:03 schrieb Steven Liu: >> Dear all, >> There are several ways to get the particle size. But I want to try "intersect line method". I know how to get the "Plot Profile". However, I do not know how to get the particle size automatically. Imaging I have many images, it will be convenient to apply Macros. >> Is there available Macros for use? I failed to find one. >> Could anyone help me? >> I attached one example image. >> Thanks! >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> > > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > Page Title > > > > > > > > När du har kontakt med oss på Uppsala universitet med e-post så innebär > det att vi behandlar dina personuppgifter. För att läsa mer om hur vi > gör det kan du läsa här: http://www.uu.se/om-uu/dataskydd-personuppgifter/ > > E-mailing Uppsala University means that we will process your personal > data. For more information on how this is performed, please read here: > http://www.uu.se/en/about-uu/data-protection-policy -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Steven Liu
I don't know of any existing functions that will do what you want.
But if you choose a manual pixel-scan based approach it is not too difficult. Try the below macro. You can re-run the macro on the segmented image to get a new analysis if you need to adjust some options. I wrote this in vanilla ImageJ 1.52m, with a manual install of "Statistical Region Merging", as discussed in a previous post. I think the analysis here would give more or less statistically valid results if you do this in both X and Y directions. The example below is only for X direction. Since the "particles" are merged into a mesh, the line intercept method should provide an estimate of the mesh "width". There might be other approaches that are better; for example making an EDM, and then masking it with the skeleton of the mesh. The greylevel histogram will then provide a distribution of the shortest mesh-width at all points. if (bitDepth == 8) { //is original image, do segmentation run("Statistical Region Merging", "q=5 showaverages"); setThreshold(115.0000, 1e30); } if (bitDepth == 32) { //is segmented image, do analysis run("Clear Results"); getThreshold(lowerThreshold, upperThreshold); numLinesPerHeight = 20; lineStep = round(getHeight/numLinesPerHeight); lastTransition = 0; start = 0; stop = 0; counter = 0; setColor("yellow"); setLineWidth(1); Overlay.remove(); for (y=0; y < getHeight; y+= lineStep) { withinParticle = false; withinThreshold = false; for (x=0; x < getWidth; x++) { v = getPixel(x,y); withinThreshold = (v >= lowerThreshold); if (!withinParticle && withinThreshold) { //we just entered a particle start = x; withinParticle = true; } if (withinParticle && !withinThreshold || (x==getWidth-1)) { //we just left a particle, or reached the right edge of the image stop = x-1; withinParticle = false; Overlay.drawLine(start, y, stop, y); setResult("X", counter, x); setResult("Y", counter, y); setResult("Length", counter, (stop-start)); counter ++; } } } Overlay.show(); } -----Original Message----- From: ImageJ Interest Group <[hidden email]> On Behalf Of Steven Liu Sent: 24. februar 2019 15:04 To: [hidden email] Subject: particle size by using intersect line? Dear all, There are several ways to get the particle size. But I want to try "intersect line method". I know how to get the "Plot Profile". However, I do not know how to get the particle size automatically. Imaging I have many images, it will be convenient to apply Macros. Is there available Macros for use? I failed to find one. Could anyone help me? I attached one example image. Thanks! -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html intersect line.tif (SRM Q=5-1.0).png (10K) Download Attachment |
Good day Stein,
I think what the "Statistical Region Merging"-plugin (interesting approach!) is able to provide is exactly what the OP was looking for. After binarization one needs to count the white or black pixels to obtain the desired area of the meander object or the back ground (No line intersections required.) Regards Herbie :::::::::::::::::::::::::::::::::::::::::: Am 03.03.19 um 22:34 schrieb Stein Rørvik: > I don't know of any existing functions that will do what you want. > But if you choose a manual pixel-scan based approach it is not too difficult. > Try the below macro. > > You can re-run the macro on the segmented image to get a new analysis if you need to adjust some options. I wrote this in vanilla ImageJ 1.52m, with a manual install of "Statistical Region Merging", as discussed in a previous post. > > I think the analysis here would give more or less statistically valid results if you do this in both X and Y directions. The example below is only for X direction. Since the "particles" are merged into a mesh, the line intercept method should provide an estimate of the mesh "width". There might be other approaches that are better; for example making an EDM, and then masking it with the skeleton of the mesh. The greylevel histogram will then provide a distribution of the shortest mesh-width at all points. > > if (bitDepth == 8) { > //is original image, do segmentation > run("Statistical Region Merging", "q=5 showaverages"); > setThreshold(115.0000, 1e30); > } > > if (bitDepth == 32) { > //is segmented image, do analysis > run("Clear Results"); > getThreshold(lowerThreshold, upperThreshold); > numLinesPerHeight = 20; > lineStep = round(getHeight/numLinesPerHeight); > lastTransition = 0; > start = 0; > stop = 0; > counter = 0; > setColor("yellow"); > setLineWidth(1); > Overlay.remove(); > for (y=0; y < getHeight; y+= lineStep) { > withinParticle = false; > withinThreshold = false; > for (x=0; x < getWidth; x++) { > v = getPixel(x,y); > withinThreshold = (v >= lowerThreshold); > if (!withinParticle && withinThreshold) { > //we just entered a particle > start = x; > withinParticle = true; > } > if (withinParticle && !withinThreshold || (x==getWidth-1)) { > //we just left a particle, or reached the right edge of the image > stop = x-1; > withinParticle = false; > Overlay.drawLine(start, y, stop, y); > setResult("X", counter, x); > setResult("Y", counter, y); > setResult("Length", counter, (stop-start)); > counter ++; > } > } > } > Overlay.show(); > } > > -----Original Message----- > From: ImageJ Interest Group <[hidden email]> On Behalf Of Steven Liu > Sent: 24. februar 2019 15:04 > To: [hidden email] > Subject: particle size by using intersect line? > > Dear all, > There are several ways to get the particle size. But I want to try "intersect line method". I know how to get the "Plot Profile". However, I do not know how to get the particle size automatically. Imaging I have many images, it will be convenient to apply Macros. > Is there available Macros for use? I failed to find one. > Could anyone help me? > I attached one example image. > Thanks! > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Steven Liu
Dera Herbie,
Many thanks for your kind help and effort. I have tried your codes. it works well. I will try to modify it for other cases. For the segmentation, Stein's method also works well and is easy to follow. Best regards, Steven -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Steven Liu
Hi, Stein,
Thanks again for your help. I have tried your codes. It seems fine. My example image may be not so good for this topic. I could have provided the segmented one. But my target is to get the distances between nearby particles or similar objects along one line without manual checking the intersecting edges in "plot of intersect line". Thanks. Best regards, Steven -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |