I have a OpenCv Image likewise;
opencvImage = cv2.cvtColor(numpy_image, cv2.COLOR_RGBA2BGRA)
Then with the following code piece, I want to remove the transparency and set a White background.
source_img = cv2.cvtColor(opencvImage[:, :, :3], cv2.COLOR_BGRA2GRAY)
source_mask = opencvImage[:,:,3] * (1 / 255.0)
background_mask = 1.0 - source_mask
bg_part = (background_color * (1 / 255.0)) * (background_mask)
source_part = (source_img * (1 / 255.0)) * (source_mask)
result_image = np.uint8(cv2.addWeighted(bg_part, 255.0, source_part, 255.0, 0.0))
Actually, I am able to set the background white, however, the actual image color is change, as well. I believe COLOR_BGRA2GRAY methods causes this problem. That's why, I tried to use IMREAD_UNCHANGED method, but I have this error : unsupported color conversion code in function 'cvtColor’
Btw, I am open to any solution, I just share my code - might need a small fix.
Here's a basic script that will replace all fully transparent pixels with white and then remove the alpha channel.
import cv2
#load image with alpha channel. use IMREAD_UNCHANGED to ensure loading of alpha channel
image = cv2.imread('your image', cv2.IMREAD_UNCHANGED)
#make mask of where the transparent bits are
trans_mask = image[:,:,3] == 0
#replace areas of transparency with white and not transparent
image[trans_mask] = [255, 255, 255, 255]
#new image without alpha channel...
new_img = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
I do not know exactly what that error is, but I was testing just now a possible solution for you. Even it is in C++, I guess you can convert it easily to python.
/* Setting data info */
std::string test_image_path = "Galicia.png";
/* General variables */
cv::namedWindow("Input image", cv::WINDOW_NORMAL);
cv::namedWindow("Input image R", cv::WINDOW_NORMAL);
cv::namedWindow("Input image G", cv::WINDOW_NORMAL);
cv::namedWindow("Input image B", cv::WINDOW_NORMAL);
cv::namedWindow("Input image A", cv::WINDOW_NORMAL);
cv::namedWindow("Output image", cv::WINDOW_NORMAL);
/* Process */
cv::Mat test_image = cv::imread(test_image_path, cv::IMREAD_UNCHANGED);
std::cout << "Image type: " << test_image.type() << std::endl;
// Split channels of the png files
std::vector<cv::Mat> pngChannels(4);
cv::split(test_image, pngChannels);
cv::imshow("Input image", test_image);
cv::imshow("Input image R", pngChannels[0]);
cv::imshow("Input image G", pngChannels[1]);
cv::imshow("Input image B", pngChannels[2]);
cv::imshow("Input image A", pngChannels[3]);
// Set to 255(white) the RGB channels where the Alpha channel(mask) is 0(transparency)
pngChannels[0].setTo(cv::Scalar(255), pngChannels[3]==0);
pngChannels[1].setTo(cv::Scalar(255), pngChannels[3]==0);
pngChannels[2].setTo(cv::Scalar(255), pngChannels[3]==0);
// Merge again the channels
cv::Mat test_image_output;
cv::merge(pngChannels, test_image_output);
// Show the merged channels.
cv::imshow("Output image", test_image_output);
// For saving with changes, conversion is needed.
cv::cvtColor(test_image_output, test_image_output, cv::COLOR_RGBA2RGB);
cv::imwrite("Galicia_mod.png", test_image_output);
I complement the code with this screenshot that may help you to understand better my solution:
Best Wishes, Arritmic
All previous answers use binarizing but mask can be non binary. In that case you can use alpha blending with white background
def alpha_blend_with_mask(foreground, background, mask): # modified func from link
# Convert uint8 to float
foreground = foreground.astype(float)
background = background.astype(float)
# Normalize the mask mask to keep intensity between 0 and 1
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
mask = mask.astype(float) / 255
# Multiply the foreground with the mask matte
foreground = cv2.multiply(mask, foreground)
# Multiply the background with ( 1 - mask )
background = cv2.multiply(1.0 - mask, background)
# Add the masked foreground and background.
return cv2.add(foreground, background).astype(np.uint8)
img_with_white_background = alpha_blend_with_mask(img[..., :3], np.ones_like(clip_img) * 255, img[..., 3])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With