What's Wrong with this code?
pczjrh
I seem to be having some issues with this code.
What it is meant to do is:
Take a large image stored in a wave R2.
Generate a random position, and check to see if the coordinates fall inside the image; if they do then
- Duplicate a small section of the image and perform a particle analysis on it
- Count the number of particles that fall within certain critiera
- Store the result in a wave as the coordinates/result
If the small section falls outside of the larger image then just ignore those coordinates.
It runs fine the first time round, but then stops on the second, it runs, but just says it finds 0 particles.
I notice that the variables are mainly but do not understand why. I kill the waves not in use.
Any help would go as long way here!
Cheers,
Jason.
#pragma rtGlobals=1 // Use modern global access method.
Function RandomParticlesAnalysis(R2)
Wave R2
Wave XArea
Wave Perim
Wave Circ
Variable wlen,i,j,Particle_Counter
Variable Fill_Counter
Variable k,l,rows,cols,offset,LeftX,LeftY,RightX,RightY,SizeX,SizeY,RandX,RandY
rows=DimSize(R2,0)
cols=DimSize(R2,1)
SizeX=500
SizeY=1000
Make/N=(rows-SizeX,cols-SizeY) NBL
for(k=0;k<50;k+=1)
//Generate a Random position to cut from the Master Image
RandX=enoise(rows)+rows
RandY=enoise(cols)+cols
RandX=round(RandX/2)
RandY=round(RandY/2)
LeftX=RandX
LeftY=RandX+SizeX
RightX=RandY
RightY=RandY+SizeY
//Check if it crops the edges.
If (LeftX<rows-SizeX)
if (RightY<cols-SizeY)
//Doesn't Crop, so Lets Split out and analyse
Duplicate/R=(LeftX,RightX)(LeftY,RightY) R2 Chip
ImageThreshold/I/T=(60)/Q root:Chip
ImageAnalyzeParticles /E/W/Q/M=3/A=25 stats, root:M_ImageThresh
Duplicate W_ImageObjArea root:XArea
Duplicate W_Circularity Circ
Duplicate W_ImageObjPerimeter Perim
//Now count the particles
wlen = numpnts(XArea)
i=0; Fill_Counter =0; Particle_Counter = 0
do
if (XArea[i] > 700 && XArea[i] <1200)
if (Perim[i] > 90 && Perim[i] < 135)
if (Circ[i]>1 & Circ[i]<1.2)
Fill_Counter = Fill_Counter + 1
else
Particle_Counter = Particle_Counter +1
endif
else
Particle_Counter =Particle_Counter +1
endif
else
Particle_Counter =Particle_Counter +1
endif
i=i+1
while (i<wlen)
//Report the findings
Print ("Found "+ num2str(Fill_Counter) + " Particles")
//Store them in the Wave to Plot Later
NBL[LeftX][RightY]=Fill_Counter
//Tidy up and report where we have just been
Print LeftX, LeftY, RightX, RightY, " at itteration: ", k
KillWaves/A/Z
//Print "---------------------------"
endif
endif
KillWaves/A/Z
endfor
End Function
Function RandomParticlesAnalysis(R2)
Wave R2
Wave XArea
Wave Perim
Wave Circ
Variable wlen,i,j,Particle_Counter
Variable Fill_Counter
Variable k,l,rows,cols,offset,LeftX,LeftY,RightX,RightY,SizeX,SizeY,RandX,RandY
rows=DimSize(R2,0)
cols=DimSize(R2,1)
SizeX=500
SizeY=1000
Make/N=(rows-SizeX,cols-SizeY) NBL
for(k=0;k<50;k+=1)
//Generate a Random position to cut from the Master Image
RandX=enoise(rows)+rows
RandY=enoise(cols)+cols
RandX=round(RandX/2)
RandY=round(RandY/2)
LeftX=RandX
LeftY=RandX+SizeX
RightX=RandY
RightY=RandY+SizeY
//Check if it crops the edges.
If (LeftX<rows-SizeX)
if (RightY<cols-SizeY)
//Doesn't Crop, so Lets Split out and analyse
Duplicate/R=(LeftX,RightX)(LeftY,RightY) R2 Chip
ImageThreshold/I/T=(60)/Q root:Chip
ImageAnalyzeParticles /E/W/Q/M=3/A=25 stats, root:M_ImageThresh
Duplicate W_ImageObjArea root:XArea
Duplicate W_Circularity Circ
Duplicate W_ImageObjPerimeter Perim
//Now count the particles
wlen = numpnts(XArea)
i=0; Fill_Counter =0; Particle_Counter = 0
do
if (XArea[i] > 700 && XArea[i] <1200)
if (Perim[i] > 90 && Perim[i] < 135)
if (Circ[i]>1 & Circ[i]<1.2)
Fill_Counter = Fill_Counter + 1
else
Particle_Counter = Particle_Counter +1
endif
else
Particle_Counter =Particle_Counter +1
endif
else
Particle_Counter =Particle_Counter +1
endif
i=i+1
while (i<wlen)
//Report the findings
Print ("Found "+ num2str(Fill_Counter) + " Particles")
//Store them in the Wave to Plot Later
NBL[LeftX][RightY]=Fill_Counter
//Tidy up and report where we have just been
Print LeftX, LeftY, RightX, RightY, " at itteration: ", k
KillWaves/A/Z
//Print "---------------------------"
endif
endif
KillWaves/A/Z
endfor
End Function
I see you are doing a KillWaves/A/Z at various points. If you are using Igor 6.1x, you might consider making FREE waves instead.
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
November 10, 2009 at 01:31 pm - Permalink
>It runs fine the first time round, but then stops on the second, it runs, but just says it finds 0 particles.
Does it stop or run to completion?
What exactly is the symptom?
What does this mean?
>I notice that the variables are mainly but do not understand why.
November 10, 2009 at 11:07 pm - Permalink
The /O switch solved one problem.
The other one, which took me a while to spot was the name of my variable LeftX and RightX, which are functions in Igor! Doh.
I changed the variable names, and a lot of stuff started to work better.
I have cleaned up my code so that it now does what I intended it to do.
It does take an age to run - I run through several tens of 1000's of cycles, but my images are very large.
If there are any suggestions as how to speed this up, that would be great otherwise, the solution is below.
Cheers,
Jason.
Function ChipAnalysis(R2,Cycles)
Wave R2
Variable Cycles
Wave XArea
Wave Perim
Wave Circ
Variable wlen,i,j,Particle_Counter
Variable/G Fill_Counter
Variable a,k,l,m,n,rows,cols,offset,Start_X,Start_Y,End_X,End_Y,SizeX,SizeY,RandX,RandY
rows=DimSize(R2,0)
cols=DimSize(R2,1)
SizeX=4200
SizeY=500
m=rows-SizeX
n=cols-SizeY
Make/O/N=(m,n) NBL
a=1
for(k=0;k<Cycles;k+=1)
//Generate a Random position to cut from the Master Image
RandX=enoise(rows)
RandY=enoise(cols)
RandX=round(sqrt(RandX^2))
RandY=round(sqrt(RandY^2))
Start_X=RandX
Start_Y=RandY
End_X=Start_X+SizeX
End_Y=Start_Y+SizeY
//Check if it crops the edges.
If (Start_X<m)
if (End_Y<n)
//Doesn't Crop, so Lets Split out and analyse
Duplicate/O/R=(Start_X,End_X)(Start_Y,End_Y) R2 AreaOfInterest
ImageThreshold/I/T=(60)/Q root:AreaOfInterest
ImageAnalyzeParticles /E/W/Q/M=3/A=25 stats, root:M_ImageThresh
Duplicate/O W_ImageObjArea XArea
Duplicate/O W_Circularity Circ
Duplicate/O W_ImageObjPerimeter Perim
CountParticles(XArea,Circ,Perim)
//Store them in the Wave to Plot Later
NBL[Start_X][Start_Y]=Fill_Counter
//Tidy up and report where we have just been
if (a==100)
Print "Count= " , NBL[Start_X][Start_Y] , " at itteration: ", k, " - Percent Complete: ", (k/cycles)*100
a=1
Endif
a=a+1
KillWaves M_ImageThresh,W_ImageObjArea,W_SpotX,W_SpotY,W_circularity;DelayUpdate
KillWaves W_rectangularity,W_ImageObjPerimeter,W_xmin,W_xmax,W_ymin,W_ymax;DelayUpdate
KillWaves M_Moments,M_RawMoments,W_BoundaryX,W_BoundaryY,W_BoundaryIndex;DelayUpdate
KillWaves M_Particle, XArea, Circ, Perim, AreaOfInterest
// Print "---------------------------"
endif
endif
endfor
End Function
Function CountParticles(XArea,Circ,Perim)
Wave XArea
Wave Perim
Wave Circ
Variable wlen,i,j,Particle_Counter
Variable/G Fill_Counter
Fill_Counter =0; Particle_Counter = 0
wlen = numpnts(XArea)
i=0; Fill_Counter =0; Particle_Counter = 0
do
if (XArea[i] > 700 && XArea[i] <1200)
if (Perim[i] > 90 && Perim[i] < 135)
if (Circ[i]>1 & Circ[i]<1.2)
Fill_Counter = Fill_Counter + 1
else
Particle_Counter = Particle_Counter +1
endif
else
Particle_Counter =Particle_Counter +1
endif
else
Particle_Counter =Particle_Counter +1
endif
i=i+1
while (i<wlen)
End
November 11, 2009 at 06:13 am - Permalink
November 11, 2009 at 09:23 am - Permalink
I have looked at your code and I'm still wondering exactly what you are trying to accomplish. Feel free to send me an experiment containing the code and sample data together with an explanation of exactly what you want to do and I'll help you with the code.
A.G.
WaveMetrics, Inc.
November 11, 2009 at 09:37 am - Permalink
As for the purpose...
I have a very large image that has many circles of a specific size on it. I want to cut certain sized sections out and count the number of circles in the sub-image. The cutout size is relevant to my application. I then record the number in a matrix such that I can develop a 'density map' of the output. I could use the ratio of white pixels to black to estimate a value, but these need to be specific sized circles that I count.
Ideally, I would start at the top and work down each row, then column, until the whole map is built. Because the image is large (120MB 8-bit) this would take a long time. So, I proposed to randomly select 10% of the image and store the data, which gives me rough idea of what the density map would look like if it were run to completion.
Cheers,
Jason
November 15, 2009 at 04:57 am - Permalink