I'm trying to find a good interval of colors for color masking in order to extract skin from images.
I have a database with images and masks to extract skin from those images. here's an example of a sample :
I'm applying the mask for each image in order to get something like this :
I'm getting all the pixels from all the masked images and removing the black pixels in order to keep only the pixels containing the skin. Using this method I'm able to gather different pixels containing different shades of color of different skins from different people.
This is the code I'm using for this :
for i, (img_color, img_mask) in enumerate ( zip(COLORED_IMAGES, MASKS) ) :
# masking
img_masked = cv2.bitwise_and(img_color, img_mask)
# transforming into pixels array
img_masked_pixels = img_masked.reshape(len(img_masked) * len(img_masked[0]), len(img_masked[0][0]))
# merging all pixels from all samples
if i == 0:
all_pixels = img_masked_pixels
else:
all_pixels = np.concatenate((all_pixels, img_masked_pixels), axis = 0)
# removing black
all_pixels = all_pixels[ ~ (all_pixels == 0).all(axis = 1) ]
# sorting pixels
all_pixels = np.sort(all_pixels)
# reshape into 1 NB_PIXELSx1 image in order to create histogram
all_pixels = all_pixels.reshape(len(all_pixels), 1, 3)
# creating image NB_PIXELSx1 image containing all skin colors from dataset samples
all_pixels = cv2.cvtColor(all_pixels, cv2.COLOR_BGR2YCR_CB)
After extracting all shades of color from different skins, I'm creating a histogram that allows me to see which colors are more common. The code is too long for the creation of the histogram, but this is the result :
Then, I use the turning point for each color space graph and chose a distance for that color space, say 20. The interval for that color space is gotten by doing [ turning point - 20, turning point +20 ]
So let's say that we got the following :
R :
- turning point : 142
- distance : 61
- interval : [81, 203]
G :
- turning point : 155
- distance : 10
- interval : [145, 165]
B :
- turning point : 109
- distance : 14
- interval : [95, 123]
I would use these intervals in order to create masks of the colored image from the dataset in order to extract the skin (left: my intervals mask, right: ground truth mask):
The extracted masks using my intervals are compared with the dataset preexistent masks and the accuracy is calculated in order to see how effective and good the intervals that I got are :
precision_moy = 0
accuracy_moy = 0
for i, (image, img) in enumerate ( zip(COLORED, GROUND_TRUTH) ) :
Min = np.array([81, 145, 95], np.uint8)
Max = np.array([203, 165, 123], np.uint8)
mask = cv2.inRange (image, Min, Max)
TP = 0 # True Positive
TN = 0 # True Negative
FP = 0 # False Positive
FN = 0 # False Negative
for i in range(mask.shape[0]) :
for j in range(mask.shape[1]) :
if mask[i,j] == 255 and img[i,j,0] == 255:
TP = TP + 1
if mask[i,j] == 0 and img[i,j,0] == 0:
TN = TN+1
if mask[i,j] == 255 and img[i,j,0] == 0:
FP = FP+1
if mask[i,j] == 0 and img[i,j,0] == 255:
FN = FN+1
precision = TP/(TP+FP)
accuracy = (TP+TN)/(TP+TN+FP+FN)
precision_moy = precision_moy + precision
accuracy_moy = accuracy_moy + accuracy
precision_moy = precision_moy / len(COLORED)
accuracy_moy = accuracy_moy / len(COLORED)
I keep on changing the intervals, testing and calculating the accuracy, in order to find the best possible interval for each color space. This change is done by multiplying the distance by a number between 0 and 2. For example :
OLD R :
- turning point : 142
- distance : 61
- interval : [81, 203]
NEW DISTANCE = OLD DISTANCE * 0.7 = 61 * 0.7 = 43
NEW R:
- turning point : 142
- distance : 43
- interval : [99, 185]
- To get a higher interval I would multiply by a number in ]1, 2]
- To get a smaller interval I would multiply by a number in ]0, 1[
Now, to my question:
I would like to find the best possible interval for each color space using an optimization method instead of manually and randomly changing the intervals. What optimization method should I use and how would I use it ?
Thank you for taking the time. Your help is appreciated.
from How to use an optimization algorithm to find the best possible parameter
No comments:
Post a Comment