I am trying to detect skin. I found a nice and easy formula to detect skin from RGB picture. The only problem is, that for loops are very slow, and I need to accelerate the process. I've done some researching and vectorization could fasten my for-loops, but I don't know how to use it in my case.
Here is code of my function:
Function receives 1 parameter of type: numpy array, with shape of (144x256x3), dtype=np.uint8
Function returns coordinates of first detected skin colored pixel(as numpy.array [height,width]); number of skin detected pixels(int) and calculated angle (from left to right) of first skin detected picture(float)
# picture = npumpy array, with 144x256x3 shape, dtype=np.uint8
def filter_image(picture):
r = 0.0
g = 0.0
b = 0.0
# In first_point I save first occurrence of skin colored pixel, so I can track person movement
first_point = np.array([-1,-1])
# counter is used to count how many skin colored pixels are in an image (to determine distance to target, because LIDAR isn't working)
counter = 0
# angle of first pixel with skin color (from left to right, calculated with Horizontal FOV)
angle = 0.0
H = picture.shape[0]
W = picture.shape[1]
# loop through each pixel
for i in range(H):
for j in range(W):
# if all RGB are 0(black), we take with next pixel
if(int(picture[i,j][0]+picture[i,j][1]+picture[i,j][2])) == 0:
continue
#else we calculate r,g,b used for skin recognition
else:
r = picture[i,j][0]/(int(picture[i,j][0]+picture[i,j][1]+picture[i,j][2]))
g = picture[i,j][1]/(int(picture[i,j][0]+picture[i,j][1]+picture[i,j][2]))
b = picture[i,j][2]/(int(picture[i,j][0]+picture[i,j][1]+picture[i,j][2]))
# if one of r,g,b calculations are 0, we take next pixel
if(g == 0 or r == 0 or b == 0):
continue
# if True, pixel is skin colored
elif(r/g > 1.185 and (((r * b) / math.pow(r + b + g,2)) > 0.107) and ((r * g) / math.pow(r + b + g,2)) > 0.112):
# if this is the first point with skin colors in the whole image, we save i,j coordinate
if(first_point[0] == -1):
# save first skin color occurrence
first_point[0] = i
first_point[1] = j
# here angle is calculated, with width skin pixel coordinate, Hor. FOV of camera and constant
angle = (j+1)*91 *0.00390626
# whenever we detect skin colored pixel, we increment the counter value
counter += 1
continue
# funtion returns coordinates of first skin colored pixel, counter of skin colored pixels and calculated angle(from left to right based on j coordinate of first pixel with skin color)
return first_point,counter, angle
Function works well, the only problem is its speed!
Thank you, for helping!
picture.dtypeplease?continueout of the loop if any RGB component is zero. You might as well test if any is zero up front andcontinueout without calculating the averages, surely?