OpenCV - Add a transparent channel to the picture, merge the transparent channel into the picture

1 Add a transparent channel to the image

Generally, the AI ​​model related to portrait cutout will output a Mask map. This Mask map is the Alpha channel information we need to cut out the characters. We need to attach this Mask map to the original image and convert it from a BGR image to a BGRA image. Or convert from an RGB image to an RGBA image.

cv::splitIf you use OpenCV for image processing, you will use the and method when adding a transparent channel to the image cv::merge. First use cv::splitthe method to separate each channel of the original image, then add the Mask to the original channel, and finally use the cv::mergesynthesized new channel to generate the final image.

The sample code is as follows

#include "opencv2/opencv.hpp"

cv::Mat MergeAlpha(const cv::Mat& src_image, const cv::Mat& alpha_image)
{
    
    
	std::vector<cv::Mat> channels;
	cv::split(src_image, channels);
	channels.push_back(alpha_image);
	cv::Mat src_alpha;
	cv::merge(channels, src_alpha);
	return src_alpha;
}

It should be noted that the Mask image must have the same resolution size and the same data type as the original image. For example, if the original image is a 1920x1080, CV_8UC3 image, then the Mask image must be a 1920x1080, CV_8UC1 image.

If your OpenCV is compiled with CUDA, you can also modify the above code to the CUDA version

cv::Mat MergeAlphaCUDA(const cv::Mat& src_image, const cv::Mat& alpha_image)
{
    
    
	cv::cuda::GpuMat src_image_gpu;
	src_image_gpu.upload(src_image);

	cv::cuda::GpuMat alpha_image_gpu;
	alpha_image_gpu.upload(alpha_image);

	std::vector<cv::cuda::GpuMat> channels;
	cv::cuda::split(src_image_gpu, channels);
	channels.push_back(alpha_image_gpu);
	cv::cuda::GpuMat src_alpha_gpu;
	cv::cuda::merge(channels, src_alpha_gpu);

	cv::Mat result;
	src_alpha_gpu.download(result);

	src_image_gpu.release();
	alpha_image_gpu.release();
	src_alpha_gpu.release();

	for (int i = 0; i < channels.size(); ++i)
	{
    
    
		channels[i].release();
	}

	return result;
}

Logically speaking, using the CUDA version of OpenCV for calculations will be much faster than using the CPU. However, after I tested the running time of the above CPU and CUDA versions, I found that the final processing time is about the same. I analyzed that the reason for this is that I am using CUDA. When versioning, the image usage method on the CPU needs uploadto be transferred from the memory to the video memory. After the calculation is completed, the final result image needs to be downloadtransferred from the video memory to the memory through the method. If the image is relatively large, HostToDevice and DeviceToHost are more time-consuming. of.

reference link

If you are interested, you can visit my personal website: https://www.stubbornhuang.com/

Guess you like

Origin blog.csdn.net/HW140701/article/details/131674594