I'm trying to do some analysis of a curly human hair on an iPhone app. I've been using the openCV library.

Particularly I want to be able to estimate the length of the hair, and locate its end points (a measure of curliness is stretched end-to-end length vs. relaxed end-to-end length).

My approach so far has been to use a canny edge detector to find the hair. Then to dilate the result. Finally to skeletonise the image and consider the ends to be those pixels that only have one neighbour. Since the resulting image would hopefully be a one pixel thick line, I could just count the pixels to estimate the length (and maybe adjust for diagonal movements).

The trouble is when the hair is so curly it crosses itself. This makes the skeletonisation add in extra branches and rings that mess up the results.

Is there a better approach for very curly hairs?

Some examples: Straight hair before

Straight hair after

Curly hair before

Curly hair after

Curly hair zoomed


1 Answer 1


Note that once you obtain the skeleton, it is very hard to reverse back to separate the connected components that should not be connected.

The problem is that your original image contrast is too low. I would operate an open morphological operation on your raw image to remove the background, hence increase the contrast of hair.

Your raw image (reverse each pixel by 255-I):

enter image description here

Background ( Open operation with the 20*20 all ones kernel, in order to remove the dark regions, along with the small, thin bright regions, only keep the large bright regions, which are viewed as the noisy background):

enter image description here

Subtract the background from the raw image, and binarize the output, you have:

enter image description here

Next I would do a dilation with the kernel:

[0 0 1;...
 0 1 0;...
 1 0 0]

Remove the small isolated object, you have:

enter image description here

Finally you extract the skeleton:

enter image description here

Looks better than your result.

The most important step is the binarization part. The better you can obtain after thresholding, the easier you will implement the skeleton extraction. And the contrast enhancement is the key operation during binarization process.

  • $\begingroup$ That looks much better! Thanks for the answer. I'm still worried that it might give odd behaviour if the hair is actually touching itself. Also, I'll look into "de-pruning" the skeleton, to help with identifying the end points. $\endgroup$ Feb 18, 2014 at 10:56
  • 1
    $\begingroup$ Yes the small branches on the skeleton can be removed by the location of end points, without touching the small objects. This can be easily done with Matlab morphological operation called 'spur'. Unfortunately opencv seems not have the corresponding function, and you may have to write a simple one by yourself. $\endgroup$
    – lennon310
    Feb 19, 2014 at 16:26

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.