6
$\begingroup$

Consider a binary image img as

enter image description here

How can I make the edges thin and smooth?

$\endgroup$
3
  • 3
    $\begingroup$ Have you tried Thinning? $\endgroup$
    – user484
    Feb 28 '18 at 10:46
  • $\begingroup$ @Rahul Thanks, it works. Although the roughness is still there. $\endgroup$
    – Majis
    Feb 28 '18 at 10:51
  • $\begingroup$ Related my this post $\endgroup$
    – yode
    Mar 6 '18 at 12:07
6
$\begingroup$

You can get it to be a little smoother by dilating before the thinning:

img = Import["https://i.stack.imgur.com/z0Vet.png"]
Thinning[Dilation[img, 1]]

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ Just about any smoothing before thinning works: Thinning[Binarize[GaussianFilter[img, 3]]] produces very similar results with maybe slightly smoother eyes. $\endgroup$
    – kjosborne
    Feb 28 '18 at 15:53
3
$\begingroup$

Riding off Bill's answer, we can smooth further by upsampling with ImageMesh, thinning, then downsampling.

img = ImageCrop[Import["https://i.stack.imgur.com/z0Vet.png"]];
imsmall = Thinning[Dilation[img, 1]];

mesh = ImageMesh[imsmall, ImageSize -> 1200, 
  Background -> Black, BaseStyle -> White, Method -> "DualMarchingCubes"];

imlarge = Thinning[Dilation[Rasterize[mesh, "Image"], 12]];

res = Thinning[Binarize[ImageResize[imlarge, ImageDimensions[img]]]]

enter image description here

Edit

Notice one side of each feature boundary is fairly smooth. I exploit this with a very manual approach:

level1 = Thinning[EdgeDetect[FillingTransform[img]]];

level2 = Thinning[EdgeDetect[FillingTransform[Dilation[
  ImageDifference[img, GeodesicClosing[img, 14]], 1]]]];

level3 = Thinning[EdgeDetect[Dilation[
  ImageDifference[img, GeodesicClosing[img, 8]], 1]]];

res = level1 + level2 + level3

enter image description here

Dilation[res, 1]

enter image description here

$\endgroup$
5
  • $\begingroup$ Is there any python implementation of this? $\endgroup$ Apr 26 '20 at 18:55
  • $\begingroup$ Can you please help me with which language this is written? @Chip $\endgroup$ Apr 26 '20 at 18:56
  • $\begingroup$ @Bharath_Raja wolfram.com/language $\endgroup$
    – Chip Hurst
    Apr 26 '20 at 19:12
  • $\begingroup$ Where can I find the documentation and list of operations used in the above solution? $\endgroup$ Apr 26 '20 at 19:27
  • $\begingroup$ Here’s an example. You can search for others on the same site. reference.wolfram.com/language/ref/Dilation.html $\endgroup$
    – Chip Hurst
    Apr 26 '20 at 19:29
3
$\begingroup$

Another idea is picking out the components and then approximating each component with a smooth spline. I tried with BSpline and Bezier, perhaps it can be used as a start.

img = Import["https://i.stack.imgur.com/z0Vet.png"];
components = MorphologicalComponents[img];
components // Colorize

Mathematica graphics

For example, one of the components can be approximated like this:

pts = RandomSample[Position[components, 2], 100];
{dist, order} = FindShortestTour[pts];
pts = Part[pts, order];
BSplineCurve[pts, SplineDegree -> 100] // Graphics

Mathematica graphics

The spline degree was chosen by experimenting. The shape is not a perfect circle, but it is rather smooth. Now we do the same for the rest of the components:

smoothComponent[comp_, splineType : "Bezier" | "BSpline"] := Module[{pts, dist, order},
  pts = RandomSample[Position[components, comp], 80];
  {dist, order} = FindShortestTour[pts];
  pts = Part[pts, order];
  If[
   splineType == "BSpline",
   BSplineCurve[pts, SplineDegree -> 100],
   BezierCurve[pts, SplineDegree -> 15]
   ]
  ]

bspline = smoothComponent[#, "BSpline"] & /@ Range[2, 9];
ImageRotate[Graphics[bspline], -90 Degree]

Mathematica graphics

bezier = smoothComponent[#, "Bezier"] & /@ Range[2, 9];
ImageRotate[Graphics[bezier], -90 Degree]

Mathematica graphics

Especially the Bezier curve didn't turn out that well. I mainly wanted to show this alternative type of answer, which is different from the image processing solutions so far.

Parameters to play with: How many points to sample from each component, and what the spline degree should be for the Bezier curve and BSpline respectively.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.