13
$\begingroup$

I am trying to isolate each of the blue painted fingernails in the image. However, I am not sure what approach should be considered due to the white design on each nail interrupting the otherwise uniform nail color. This of course, makes EdgeDetect a lot harder to apply. Any suggestion would be appreciated.

i = Import["https://i.sstatic.net/46JAy.jpg"]

Mathematica graphics

+++++++++++++++++++++++++++++++++ UPDATE +++++++++++++++++++++++++++++++++++++

Thanks to both Belisarius and Vitaliy Kaurov for your in depth responses. I am trying to consider a more general case such as the following image. I would like to use an edge detection approach to find the area of the nails. using a MedianFilter does help a lot and isolates the nail areas. However, what would be the next step in using the result to detect the nail areas? I am guessing that I would need to 'complete' the circles of these lines first. Is there a better approach? Perhaps measuring the density of the lines would be the best...

i = Import["https://i.sstatic.net/6khSE.png"]

Mathematica graphics

EdgeDetect[MedianFilter[i, 4]]

Mathematica graphics

$\endgroup$
3
  • 1
    $\begingroup$ Line looks yellow to me, not white. Relevant questions: mathematica.stackexchange.com/questions/5386/… and mathematica.stackexchange.com/questions/4777/… $\endgroup$ Commented Jul 28, 2012 at 2:07
  • 1
    $\begingroup$ Your "update" seems to include a whole different world of problems. I suggest posting it in another question and also post there enough samples of nails so you don't have to "upgrade" again $\endgroup$ Commented Jul 28, 2012 at 16:21
  • 4
    $\begingroup$ Both belisarius and Vitaliy have answered your original question; if you feel they haven't, please try to clarify why. Your update is a different question (and probably way too general; is the white balance going to be correct? the colour of the nails always the same? their size always constant?). it's underspecified $\endgroup$
    – acl
    Commented Jul 28, 2012 at 17:06

2 Answers 2

20
$\begingroup$
i = Import["https://i.sstatic.net/46JAy.jpg"]
(*Let's first find the blue zone*)
(*Separate Colours and negate*)
{rr, gg, bb} = ColorNegate /@ ColorSeparate@i

Mathematica graphics

(*Increase contrast*)
msf = MeanShiftFilter[ImageMultiply[ImageMultiply[ColorNegate@bb, rr], gg], 2, .1]

Mathematica graphics

(*Binarize and delete small dots*)
blueMoon = DeleteSmallComponents[Binarize[msf], 10]

Mathematica graphics

(*Now Find zigzags*)
zigs = Binarize[ColorNegate@gg, .99]  

Mathematica graphics

(*Add zigs to moons and eat up dots*)
c = Erosion[Dilation[ImageAdd[zigs, blueMoon], 10], 10]

Mathematica graphics

We are done. Let's play a bit with the results

(*Colorize and count the fingers: 5. Another boring human being*)
(*I bet her hair is green and she has a snake tatooed down there*)
Colorize[MorphologicalComponents[c], ColorFunction -> "BrightBands"]

Mathematica graphics

(*See what we found*)
ImageMultiply[c, i]

Mathematica graphics

No tatoo :(

$\endgroup$
14
$\begingroup$

It all depends on what you mean by "isolate". Here is a start. I will use function called ClusteringComponents which finds clusters of pixels with similar values in image. We have quite a few different type of elements: skin, nails, zigzag line, a few background elements. Some have a bit close nature - like whitish-yellowish color of zigzags and the skin. So you have to specify large enough number of clusters to pick all those up, but not too big to make later search through them cumbersome. "Make everything as simple as possible, but not simpler." ~ Albert Einstein - a typical optimization statement ;-) For example, choosing number of clusters to be 8 will not be able to distinguish between zigzags and part of the skin:

i = Import["https://i.sstatic.net/46JAy.jpg"];
x = ClusteringComponents[i, 8] ; x // Colorize

enter image description here

But 9 clusters already will do:

x = ClusteringComponents[i, 9]; ArrayPlot[x]

enter image description here

From this image we see that in the array (matrix) x produced by ClusteringComponents nails and zigzags are the darkest, so they got the highest index values. Because we had 9 clusters, this line is obvious:

ArrayPlot[x, ColorRules -> {9 -> Red, 8 -> Blue}, FrameTicks -> True]

enter image description here

You can also completely remove the background:

ArrayPlot[x, ColorRules -> {9 -> Red, 8 -> Blue, _ -> White}, FrameTicks -> True]

enter image description here

And finally you can find all sorts of things, like where the centers of nails are and what is the radius of an equivalent disk:

Show[i, Graphics[{Red, Thickness[.01], Circle[#[[1]], #[[2]]] & /@ 
    ComponentMeasurements[DeleteSmallComponents[Dilation[
        Image[x /. (# -> 0 & /@ Range[7])~Join~{8 -> 1, 9 -> 1}], 
        3]], {"Centroid", "EquivalentDiskRadius"}][[All, 2]]}]]

enter image description here

$\endgroup$
2
  • $\begingroup$ William of Ockham may have touched on complexity of solutions 600 years prior to Einstein ;) $\endgroup$ Commented Aug 1, 2012 at 6:14
  • $\begingroup$ @image_doctor haha indeed - all credit goes to him ;-) $\endgroup$ Commented Aug 1, 2012 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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