Thursday, June 1, 2017

image processing - basic hsb skin detection, neon illumination


i hope this is the right place to ask. otherways sorry for my mistake and pleace advice me a better site.



i'm trying to implement a super simple skin detector using some range of hsb image. i'm using approach described here and here.


i'm try to use a video source from my webcam. if i use sun illumination it works quite well (not so good but quite good), but with neon light.. it is a mess. a lot of white region are detected and a lot of noise everywhere.


why?


i'm using the algorithm described in the second source:



  1. convert image ho HSV color space

  2. put white on the range 0 < H < 38

  3. dilate filter

  4. erode filter

  5. blur filter



enter image description here



Answer



This actually might work better using a simple generative model in RGB rather than HSV.



  1. Get a training image or several training images with some skin.

  2. Manually select the skin pixels (e. g. by creating a binary mask)

  3. Compute the mean and covariance of the skin tone in RGB (each should be 3-element vectors)

  4. For an unknown pixel, compute its Mahalanobis distance from the mean, using the covariance.

  5. Classify it as skin if the distance is less than a threshold.


  6. Tune the threshold for best performance.


Edit: I don't know if OpenCV has a function to compute covariance, but I can tell you how to do it yourself. Let's say you have $n$ RGB pixels. You put them into an $n$ x 3 matrix, let's call it $P$. Then compute $m$, which is the mean RGB vector by calculating the average of the columns. $m$ will be a 1 x 3 vector. Subtract $m$ from every row of $P$ and call the resulting matrix $Q$. Now to compute covariance, all you have to do is multiply $Q$ by the transpose of itself: $C = Q'Q$. Make sure that $C$ is 3 x 3.


Edit2: The values you are getting seem to be too large. To get the maximum covariance create the following matrix:


255 255 255
0 0 0

and compute covariance of that. You should get a matrix where every value is approximately 32513. So make sure that your pixel values range from 0 to 255, and make sure you copy them into floats or doubles correctly. The Mahalanobis distance is in the units of variance, so for that the numbers should be small. Your threshold for skin classification should probably be less than 4.


No comments:

Post a Comment

periodic trends - Comparing radii in lithium, beryllium, magnesium, aluminium and sodium ions

Apparently the of last four, $\ce{Mg^2+}$ is closest in radius to $\ce{Li+}$. Is this true, and if so, why would a whole larger shell ($\ce{...