
Find Smallest Circle Fit to Image Blob

jjweimer
This will seek the smallest circle to fit to a given shape. The inputs wx, wy are the boundaries to the shape.
Further optimizations are likely possible.
Reference Discussions
https://www.wavemetrics.com/forum/general/iso-algorithm-apply-smallest-circle-problem
https://www.wavemetrics.com/forum/general/circle-cut-edges
// calculate the smallest circle to fit boundary defined by wy, wx Function calc_SmallestCircle(wy,wx) wave wy, wx variable np, npl, npr variable px1, py1, px2, py2, px3, py3 variable vm1, vm2 // restrict to under 1000 points as needed to avoid long times np = numpnts(wx) npl = log(np) if (npl > 3) npl = trunc(npl) npr = trunc(np/10^npl) npl = (npr*10^(npl - 2))/5 duplicate/O wx wdx duplicate/O wy wdy Resample/DOWN=(npl) wdx Resample/DOWN=(npl) wdy np = numpnts(wdx) else duplicate/O wx, wdx duplicate/O wy, wdy np = numpnts(wx) endif // calculate the distances make/N=(np)/FREE/D dmaxarray dmaxarray = 0 MultiThread dmaxarray = CalcMaxDistance(wdx, wdy, np, p) // get three points make/N=3/D/FREE wpx, wpy npr = 0.03*np WaveStats/Q dmaxarray vm1 = v_maxloc wpx[0] = wdx[vm1] wpy[0] = wdy[vm1] npl = (vm1 - npr) < 0 ? 0 : vm1 - npr dmaxarray[npl,vm1 + npr] = 0 WaveStats/Q/R=(inf,vm1) dmaxarray vm2 = v_maxloc wpx[1] = wdx[vm2] wpy[1] = wdy[vm2] npl = (vm2 + npr) > (np - 1) ? np - 1 : vm2 + npr dmaxarray[vm2 - npr, npl] = 0 if ((vm2 - vm1) > (np - vm2)) WaveStats/Q/R=(vm1,vm2) dmaxarray else WaveStats/Q/R=(vm2,np-1) dmaxarray endif wpx[2] = wdx[v_maxloc] wpy[2] = wdy[v_maxloc] dmaxarray[v_maxloc] = 0 GetCircumCenter(wpx,wpy) return 0 end ThreadSafe Function CalcMaxDistance(wx,wy,np,pp) wave wx, wy variable np, pp variable rmax // create 2-D wave make/N=(np)/FREE dd = 0 // calculate distances and return maximum dd = sqrt((wx[p] - wx[pp])^2 + (wy[p] - wy[pp])^2) rmax = wavemax(dd) return rmax end Function GetCircumCenter(wpx,wpy) wave wpx, wpy variable dlen, cx, cy, rc dlen = 2*(wpy[0]*wpx[2] + wpy[1]*wpx[0] - wpy[1]*wpx[2] - wpy[0]*wpx[1] - wpy[2]*wpx[0] + wpy[2]*wpx[1]) cx = wpy[1]*wpx[0]^2 - wpy[2]*wpx[0]^2 - (wpy[1]^2)*wpy[0] + (wpy[2]^2)*wpy[0] cx += (wpx[1]^2)*wpy[2] + (wpy[0]^2)*wpy[1] + wpx[2]^2*wpy[0] - (wpy[2]^2)*wpy[1] cx += - (wpx[2]^2)*wpy[1] - (wpx[1]^2)*wpy[0] + (wpy[1]^2)*wpy[2] - (wpy[0]^2)*wpy[2] cx /= dlen cy = (wpx[0]^2)*wpx[2] + (wpy[0]^2)*wpx[2] + (wpx[1]^2)*wpx[0] - (wpx[1]^2)*wpx[2] cy += + (wpy[1]^2)*wpx[0] - (wpy[1]^2)*wpx[2] - (wpx[0]^2)*wpx[1] - (wpy[0]^2)*wpx[1] cy += - (wpx[2]^2)*wpx[0] + (wpx[2]^2)*wpx[1] - (wpy[2]^2)*wpx[0] + (wpy[2]^2)*wpx[1] cy /= dlen rc = sqrt((wpx[0] - cx)^2 + (wpy[0] - cy)^2) print "Values (cx, cy, rc) are: ", cx, cy, rc return 0 end

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More