Reputation: 841
I want to convert a color in an image thereby preserving the anti-aliasing and transparent background. The initial image is a png with transparent background:
I use the following code to convert the arrow from red to green:
import numpy as np
import cv2
image = cv2.imread("C:/Temp/arr.png")
image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
cv2.imwrite('C:/Temp/source.png', image)
image[np.where((image == [0,0,255,255]).all(axis = 2))] = [0,255,0,255]
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGBA)
image[np.all(image == [255, 255, 255, 255], axis=2)] = [255, 255, 255, 0]
cv2.imwrite('C:/Temp/target.png', image)
But the diagonal lines of the arrow-tip become very granular:
How could I improve this color conversion?
Upvotes: 1
Views: 1090
Reputation: 4826
The anti-aliasing happens within the alpha channel which you have thrown away. You need not to perform cvtColor
, but to keep the alpha channel in imread
.
Result:
import numpy as np
import cv2
image = cv2.imread("arr.png", cv2.IMREAD_UNCHANGED)
b, g, r, a = cv2.split(image)
bgr = cv2.merge((b, g, r))
all_g = np.ones_like(bgr)
all_g[:, :] = (0,255,0)
bgr = np.where(bgr == (0,0,255), all_g, bgr)
image = cv2.merge((bgr, a))
cv2.imwrite('target.png', image)
Upvotes: 1