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::split
If 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::split
the method to separate each channel of the original image, then add the Mask to the original channel, and finally use the cv::merge
synthesized 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 upload
to be transferred from the memory to the video memory. After the calculation is completed, the final result image needs to be download
transferred 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/