I want to change the color of a bulldozer to a specific Hexadecimal color (red in this case)
while preserving the intensity (the effect of light on the bulldozer).
I want to change only the yellow parts of it, so far I have created a mask with a lower and upper bounds for the light and darker yellow tones, and extracted that mask, however I don't know how to apply the color red to the mask and keep the relative intensity of the color, not just all the same tone of red.
Something like the following image would be great (better quality if possible, since there seems to be some color not correctly set)

I have seen some workarounds using HSV but nothing really does the job.
My code so far involves creating a mask to extract the color that I want to change and convert that mask to HSV colors to preserve the intensity of the colors, after that I try to modify the HSV to achieve the desired color, however it is not precise, there is no exact way to change the HSV to the hexadecimal or rgb color that I want?
import cv2
import numpy as np
import os
import math
from numpy import inf
# set the bounds for the light and dark shade of color you want to mask
lower_yellow = np.array([20, 100, 100])
upper_yellow = np.array([30, 255, 255])
all_images = sorted(os.listdir('data/audi_a6'))
for i, image in enumerate(all_images):
print(image, end='\r')
img = cv2.imread(f'data/lego/{image}')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
yellow_mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
inv_mask = cv2.bitwise_not(yellow_mask)
h, s, v = cv2.split(hsv)
h = np.mod(h - h + 182, 180)
s = np.clip(s + 120, 0, 255)
v = np.clip(v, 0, 255)
hsv = cv2.merge([h, s, v])
bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
result = cv2.bitwise_or(cv2.bitwise_and(img, img, mask=inv_mask), cv2.bitwise_and(bgr, bgr, mask=yellow_mask))
# Save the result
cv2.imwrite(f'output_change_color/lego/frame_{i:03}.jpg', result)
You seem to be having difficulty discriminating between the yellow machine and the "muddy track" beneath it. One way to work out these things is to look at different colourspaces and see which one is a good discriminant. So, I converted your image to many different colourspaces and split out the individual channels side-by-side for you:
So you could look at each channel of each colourspace and see which one works best for you. For example the third channel of
CIELab, or the second channel ofHCL...