问题描述
我在QT界面中使用opencv读取PNG图片,并将他显示在另一张已经创建好的Mat背景下时,出现了图片背景后始终会有杂乱的方块格子显示。
所以我开始了检索,通过检索发现可能是读取的时候没有将图片的透明通道读取进来,并且你的背景也应该有透明通道,才能使该透明的地方透明,该有色彩的地方有色彩。所以我采用了以下代码,来读取图片并显示。
// 读取图片
cv::Mat image = cv::imread("truck.png", cv::IMREAD_UNCHANGED);
if (image.empty()) {
std::cerr << "Error: Could not read the image." << std::endl;
return -1;
}
cv::resize(image, image, cv::Size(100, 150));
cv::Mat target_image(300, 300, CV_8UC4, cv::Scalar(255, 0, 255, 0));
// 设置图片在窗口中的位置和大小
cv::Rect roi_rect(0, 0, image.cols, image.rows); // 起始点的x坐标,y坐标,宽度,高度
cv::Mat roi = target_image(roi_rect);
image.copyTo(roi);
上面的代码是网络给的标准答案,但是我运行过后,还是PNG图像周围还是会有底色,而不是透明的。
解决方案:
最终通过检索,我的解决方案是将PNG的图片的四个通道全部分离开来,然后按照图像通道再赋值给要覆盖的背景的Mat上,运行之后发现可以解决问题。
void drawTransparency(cv::Mat& frame, cv::Mat& transp, int xPos, int yPos) {
cv::Mat mask;
std::vector<cv::Mat> layers;
split(transp, layers);
std::cout << "size: " << layers.size() << std::endl;
cv::Mat rgb[3] = { layers[0],layers[1],layers[2] };
mask = layers[3];
merge(rgb, 3, transp);
transp.copyTo(frame(cv::Rect(xPos, yPos, transp.cols, transp.rows)), mask);
}