I am trying to remove the yellow background from a set of images of this kind:
and replace it with transparency using masks using the opencv library. There is my code:
HSV_RANGES = {
# red is a major color
'red': [
{
'lower': np.array([0, 39, 64]),
'upper': np.array([20, 255, 255])
},
{
'lower': np.array([161, 39, 64]),
'upper': np.array([180, 255, 255])
}
],
# yellow is a minor color
'yellow': [
{
'lower': np.array([21, 39, 64]),
'upper': np.array([40, 255, 255])
}
],
# green is a major color
'green': [
{
'lower': np.array([41, 39, 64]),
'upper': np.array([80, 255, 255])
}
],
# cyan is a minor color
'cyan': [
{
'lower': np.array([81, 39, 64]),
'upper': np.array([100, 255, 255])
}
],
# blue is a major color
'blue': [
{
'lower': np.array([101, 39, 64]),
'upper': np.array([140, 255, 255])
}
],
# violet is a minor color
'violet': [
{
'lower': np.array([141, 39, 64]),
'upper': np.array([160, 255, 255])
}
],
# next are the monochrome ranges
# black is all H & S values, but only the lower 25% of V
'black': [
{
'lower': np.array([0, 0, 0]),
'upper': np.array([180, 255, 63])
}
],
# gray is all H values, lower 15% of S, & between 26-89% of V
'gray': [
{
'lower': np.array([0, 0, 64]),
'upper': np.array([180, 38, 228])
}
],
# white is all H values, lower 15% of S, & upper 10% of V
'white': [
{
'lower': np.array([0, 0, 229]),
'upper': np.array([180, 38, 255])
}
]
}
def create_mask(hsv_img, colors):
mask = np.zeros((hsv_img.shape[0], hsv_img.shape[1]), dtype=np.uint8)
for color in colors:
for color_range in HSV_RANGES[color]:
mask += cv2.inRange(
hsv_img,
color_range['lower'],
color_range['upper']
)
return mask
for file_name in os.listdir(fly_dataset):
file_path = os.path.join(fly_dataset, file_name)
image = cv2.imread(file_path)
#remove background
output = image
# Create HSV Image and threshold it into the proper range.
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # Converting color space from BGR to HSV
mask = create_mask(image, ['red'])
cv2_imshow(mask)
# Create the output image, using the mask created above. This will perform the removal of all unneeded colors, but will keep a black background.
output = cv2.bitwise_and(image, image, mask=mask)
# Add an alpha channel, and update the output image variable
*_, alpha = cv2.split(output)
dst = cv2.merge((output, alpha))
output = dst
#save image
cv2.imwrite(fly_png + file_name.replace("jpg", "png") , output)
However, I am not having success, since the algorithm is not intelligent and therefore removes part of the flies.
Does anyone know a way to improve this algorithm or even know a better way to solve this problem?