# Circle with cut off edges

SCooil

Sat, 12/05/2015 - 07:40 am

I am trying to figure out the diameter of a circle, the problem is that some of the edges of the circle have been cut by a rectangle (see attached wave "mask.ibw").

I have tried to use imageanalyzeparticle, with the "/E" flag but in this case the fitted circle must have the same area as the particle itself. Here however the circle needs to have a larger area than the particle as it needs to include the area of the cut off edges.

Any help would be greatly appreciated. Thanks in advance.

Depends on some assumptions you are willing to make. From your image, you could use Maximum X of particle - minimum X of particle as the diameter. Not a general solution, but it works on your test case. The requirement would be one particle with at least a diameter aligned to one axis in the field of view.

Andy

December 5, 2015 at 11:57 am - Permalink

Wouldn't this only work if the circle was centred in the rectangle?

Cheers

December 6, 2015 at 12:55 am - Permalink

Andy

December 6, 2015 at 11:38 am - Permalink

My solution is brute force and inelegant, but it appears to work. The idea is to compute the distance between all pairs of points on the boundary of the figure. If the figure includes a pair of points on a diameter, then the maximum of all the computed distances will be the diameter. If the figure doesn't include a diameter, this method will fail.

I include two variations: one where you have already used

`ImageAnalyzeParticles`

to get the pair of xy waves describing the figure boundary and a second where you begin with the binarized figure.This method gives a diameter of 1654.21. My testing shows that a circle with the calculated diameter provides a good fit to your input mask wave.

I look forward to seeing other replies with simple and beautiful solutions.

Hope this helps.

Jeff

Method 1 (starting with boundary waves)

//the boundary of the partial circle.

//If starting from and image, use ImageAnalyze particles to get the x and y boundary

//waves (W_BoundaryX and W_BoundaryY) for the object.

Function GetDistanceFromBoundary(wX, wY)

Wave wX

Wave wY

Variable vNumElements

Variable vIndex_i

Variable vIndex_j

Variable vIndex_d

Variable vX

Variable vY

Variable vDiameter

Variable vTest

vNumElements = DimSize(wX, 0 )

Make/FREE /N=(vNumElements^2) wDistance

Make/FREE /N=(vNumElements^2) wNumberOfMax

for( vIndex_i = 0; vIndex_i < vNumElements; vIndex_i += 1 )

vX = wX[vIndex_i]

vY = wY[vIndex_i]

for( vIndex_j = 0; vIndex_j < vNumElements; vIndex_j += 1 )

vIndex_d = vIndex_i * vNumElements + vIndex_j

wDistance[vIndex_d] = sqrt( (wX[vIndex_j] - vX) ^2 + (wY[vIndex_j] - vY) ^2 )

endfor

endfor

vDiameter = wavemax(wDistance)

vTest = floor(vDiameter)

print vDiameter, vTest

wNumberOfMax = wDistance > vTest ? 1 : 0

print sum(wNumberOfMax)

print "done"

End

Method 2 (starting with binarized figure)

//The source image wave must be binary, i.e., an unsigned char format where the

//particles are designated by 0 and the background by 255.

Function GetDistanceFromImage(wParticle)

Wave wParticle

imageanalyzeparticles/W stats wParticle

Wave wX = W_BoundaryX

Wave wY = W_BoundaryY

Variable vNumElements

Variable vIndex_i

Variable vIndex_j

Variable vIndex_d

Variable vX

Variable vY

Variable vDiameter

Variable vTest

vNumElements = DimSize(wX, 0 )

Make/FREE /N=(vNumElements^2) wDistance

Make/FREE /N=(vNumElements^2) wNumberOfMax

for( vIndex_i = 0; vIndex_i < vNumElements; vIndex_i += 1 )

vX = wX[vIndex_i]

vY = wY[vIndex_i]

for( vIndex_j = 0; vIndex_j < vNumElements; vIndex_j += 1 )

vIndex_d = vIndex_i * vNumElements + vIndex_j

wDistance[vIndex_d] = sqrt( (wX[vIndex_j] - vX) ^2 + (wY[vIndex_j] - vY) ^2 )

endfor

endfor

vDiameter = wavemax(wDistance)

vTest = floor(vDiameter)

print vDiameter, vTest

wNumberOfMax = wDistance > vTest ? 1 : 0

print sum(wNumberOfMax)

print "done"

End

December 7, 2015 at 06:37 am - Permalink

Jeff is correct, i miss read the image a bit. An alternative solution:

1. Find the edge points

2. Discard all the ones that are on the image boundary, 1st or last row and first or last column.

3. For each row with 2 points, then calculate the average which should lie on a diameter.

4. Repeat for the columns with 2 points also lying on a diameter.

You can fit the lines and find the intersection which will be the center.

From that point you can calculate the distance to any point on edge detected to get the radius. You can do it over all the found edge points and take an average to get the benefit of statistics.

Andy

December 7, 2015 at 09:46 am - Permalink