The statistical skin tone model in the RGB color space 1. A brief introduction to the statistical skin tone Model The parameters of the skin color model presented in previous articles, since the parameter values are fixed, the segmentation error from the test image set is likely to be large (but sufficient in the case of adequate illumination). For the dim light situation, generally people do not train such data to extract parameters, while the light is not enough color easy to mix with the background, so it is not good to make the effect. In dimly lit situations, it is still difficult to separate the complexion directly from natural light and complex backgrounds. The only discussion here is whether a single pixel is a skin color, and if it is required to split a shot or face in a large area of skin color, this non-contextual approach is doomed. So how does the statistical skin model improve compared to the parametric skin model? The parameters of the parametric skin tone model are constant, while the parameters of the statistical skin model are variable (calculated based on the trained data set) and the possibility is introduced. Jone MJ and others put forward the statistical skin color model, the parameter calculation steps are as follows:(1) using the picture training set to establish the color and non-skin color classColor Histogram;
(2) CalculationPrior probability: The probability P (Cs) belonging to the skin color class and the probability P (Cns) belonging to the non-skin color class;
(3) CalculationConditional Probabilities: The probability P (v|) in the skin color class that belongs to the color value Cs) and probability P (v|) belonging to the color value in the non-skin color class CNS);
(4) Bayesian rule calculationpost-Test probability: This color block belongs to the probability P (cs|v) of the skin color class. 2. Statistical skin color Model implementation problems picture training set dozens of to thousands of pictures, in the end with how much resolution of the picture? I have tried RGB three-channel color 8bit respectively picture (that is, single channel color with 8-bit representation), color histogram of the independent variable size of 256*256*256. The notebook ran very slowly, I endured. Finally ran out of data, stored in 2 arrays, good happy ~ Then read the data, considering the amount of training data is much larger than the amount of test data, so the code to calculate the training data and the code to calculate the test data I write separately. The test data needs to be taken from the training data that was previously run, so I added a fragment to the CSV file after the training data program. After writing to try to open the CSV file, I am stunned that the CSV file 125MB, the table open display is not complete, the text document is not open! Well, I'm not opening you up. Reading data directly is always OK, add read CSV file on the other side, appear memoryerror. The problem is that the allocated memory space for Python runs is relatively small, and even if the data is displayed, the intermediate data is skipped with "...". It is also time-consuming to run the subsequent display sections. Finally, we decided to use the 6*6*6 bit color value to make the color histogram. 3. Code implementation (1) Training code Trained data is written to the Skin_nonskin.csv file. Due to the large training data, training data is not available for the time being without special requirements.
Import Cv2import numpy as Npimport osimport csv##################################################################### ########## #print ' Set Image Directory ' imgfile = ' images/skin_color_database/skin_color_database_1/' ################ ################################################################# define variables for histogramcolorrange = 64# Skin Color Countscountskin = Np.zeros (Colorrange * * 3, np.double) # Non-skin Color Countscountnonskin = Np.zeros (ColorRange * 3 , np.double) # label sets true if it's a label image, otherwise sets false if it ' s an original Imagelabel = true########### #################################################################### #print ' Skin Color histogram ' for fileName in Os.listdir (imgfile): if label = = True: # Load a label image print ' label File Name: ', fileName Imglabel = Cv2.imread (Imgfile + fileName) # Convert color space from BGR to Gray Imglabel = Cv2.cvtcolor (Imglabel, Cv2. COLOR_bgr2gray) Else: # load an original image print ' original File Name: ', fileName img = cv2.im Read (Imgfile + fileName) ############################################################################ # count Pi Xel Color values If label = = False: # Get image shape Rows,cols,channels = Img.shape for R in range: for C in range (cols): # Get values from RGB color Space B = Img.item (r,c,0)/4 G = Img.item (r,c,1)/4 R = Img.item (r,c,2)/4 color = B * * + + G * + R if Imglabe L.item (r,c) = = 255:countskin[color] + + 1 Else:countnonskin[color] + = 1 label = Not label################################################################ ################# Data Combination#---------Countskin------------#---------Countnonskin---------data = [Countskin, countnonskin]######### ######################################################################## Write CSV filecsvfile = open (' Skin_ Nonskin.csv ', ' WB ') writer = Csv.writer (csvfile) for Row and Data:writer.writerow ([Row[col] for Col in range (colorrange * * 3]) ############################################################################### #print ' Goodbye! '
(2) test code
Import Osimport cv2import csvimport numpy as Npfrom matplotlib import pyplot as Pltfrom mpl_toolkits.mplot3d.axes3d import axes3d############################################################################### #print ' read csv file ' VRange = * 64print Vrangecountskin = Np.zeros (Vrange, np.double) Countnonskin = Np.zeros (Vrange, np.double) csvfile = open ( ' Skin_nonskin.csv ', "RB") reader = Csv.reader (csvfile) RowNum = 0for row in reader:colnum = 0 for col in row: # Restore Countskin and Countnonskin modnum = ROWNUM-ROWNUM/2 * 2 if Modnum = = 1: countnonskin[((rowNum-1) * vrange + colnum)] = float (col) if modnum = = 0 : countskin[((rowNum-1) * vrange + colnum)] = float (col) Colnum + = 1 RowNum + = 1##################################################################### ########## #print ' Skin Color DaTabase Result ' # countprint ' Count of skins pixels: ', countskinprint ' count of non-skin pixels: ', countnonskin############## ################################################################# #print ' Prior probability ' SkinPix = SUM (countSkin ) Nskinpix = SUM (countnonskin) PCs = Skinpix/(Skinpix + Nskinpix) # p (Cs) PCns = 1-pcs # p (Cns) print ' probability of skin Class: ', Pcsprint ' probability of Non-skin class ', pcns############################################################# ################## #print ' conditional probability variables ' PVCs = Np.zeros (Vrange, np.double) # P (v| Cs) Pvcns = Np.zeros (Vrange, np.double) # P (v| Cns) for I in Range (vrange): # pixel color probability given skin color pvcs[i] = countskin[i]/Skinpix # pixel C Olor probability given Non-skin color pvcns[i] = countnonskin[i]/nskinpix############################################ ################################### #print ' posterior probability ' pcsv = Np.zeros (Vrange, np.double) # P (Cs| V) for I in Range (Vrange): #Skin probability given pixel color pcsv[i] = (pvcs[i] * pcs)/(Pvcs[i] * pcs + pvcns[i] * PCns + 0.00000001) ########## ##################################################################### #print ' Determine skin distribution ' # pixel Color Rangev = Range (vrange) # skin Class Thresholdtheta = [0.6,0.7,0.8,0.9]# color of a single Classrgbcolor = Np.zeros (3, NP.UINT8) # RGB Color Valueskinpix = Np.zeros (Vrange, Np.uint8) # prepare for 3d Plotfig = plt.figure () ax = Fig.add_subplot (111, projection = ' 3d ') for I in V: # split 3 channels (64B * 64b * 64b) B = I/(* *) G = (I-b * 64 * (+)/+ R = i-b * * * 64-G * * * given probability as threshold if pcsv[i] > theta[3]: SKINP Ix[i] = 4 Ax.scatter (r, G, B, c= ' R ', marker= ' o ') else:skinpix[i] = 0################## ############################################################# #print ' Display distribution of skin color ' ax.set_ Xlabel (' Red ') ax.set_ylabel (' Green ') Ax.set_zlAbel (' Blue ') plt.show () ############################################################################### #print ' goodbye! ' <span style= "font-family:arial, Helvetica, Sans-serif; Background-color:rgb (255, 255, 255); " > </span>
This part does not count as the test code, because the test picture is not used to test the effect. Why not test it? Because the generalization error of the model depends on the training data, the perfect form of the model is a defective model based on the perfect database. At the same time, it is more intuitive to see the shape of the skin color in the RGB colour space than to test the complexion with a picture. I found it. Experimental results of the training data set: The color space is determined by the possibility of 90%,80%,70% and 60% in order from left to right, from top to bottom.
Conclusion this part of the experimental results for the training database to obtain the color of the color in the RGB space distribution. So if you give 1 pixels, you can judge the color value of the pixel by a large likelihood. It is more robust than the absolute judgment of the previous parameter skin tone model.
Statistical skin color model in the OpenCV Using Python--rgb color space