I am trying to detect skin using this proposed algorithm.
In order to so, I need to take only the pixels that fall under this category:
conditions
I can do so by "manualy" iterating over each of the image's pixel and using an if statement.
Is there a way i can use (preferably) opencv or numpy to do it more efficiently?
You can do it in the following way:
import cv2
import numpy as np
from pathlib import PosixPath
RED_MIN, RED_MAX = 20, 200
BLUE_MIN, BLUE_MAX = 20, 200
GREEN_MIN, GREEN_MAX = 20, 200
if __name__ == '__main__':
# 1) Load the image
p = PosixPath('../../Pictures/Spring.jpeg')
img = cv2.imread(str(p))
cv2.imshow('Spring', img)
# 2) Split the image into Blue, Green and Red channels
# (remember, in OpenCV the channels' order is BGR and not RGB)
blue_img = img[:, :, 0]
green_img = img[:, :, 1]
red_img = img[:, :, 2]
# 3) Create masks for each color range
blue_mask = cv2.inRange(blue_img, BLUE_MIN, BLUE_MAX)
blue_mask[np.where(blue_mask == 255)] = 1
green_mask = cv2.inRange(green_img, GREEN_MIN, GREEN_MAX)
green_mask[np.where(green_mask == 255)] = 1
red_mask = cv2.inRange(red_img, RED_MIN, RED_MAX)
red_mask[np.where(red_mask == 255)] = 1
# 4) Combine the relevant image pixels into one final image
filtered_img = np.zeros_like(img)
filtered_img[:, :, 0] = blue_img * blue_mask
filtered_img[:, :, 1] = green_img * green_mask
filtered_img[:, :, 2] = red_img * red_mask
cv2.imshow('Filtered image', filtered_img)
cv2.waitKey()
cv2.destroyAllWindows()
Cheers.