简体   繁体   English

OpenCV:具有Alpha通道的PNG图像

[英]OpenCV: PNG image with alpha channel

I'm new to OpenCV and I've done a small POC for reading an image from some URL. 我是OpenCV的新手,我做了一个小的POC,用于从某些URL读取图像。
I'm reading the image from an URL using video capture. 我正在使用视频捕获功能从URL中读取图像。 The code is as follows: 代码如下:

VideoCapture vc;
vc.open("http://files.kurento.org/img/mario-wings.png");
if(vc.isOpened() && vc.grab()) 
{
       cv::Mat logo;
       vc.retrieve(logo);
       cv::namedWindow("t");
       imwrite( "mario-wings-opened.png", logo);
       cv::imshow("t", logo);
       cv::waitKey(0);
       vc.release();
}

This image is not opened correctly, possibly due to alpha channel. 可能由于Alpha通道,此图像无法正确打开。 What is the way to preserve alpha channel and get the image correctly? 保留Alpha通道并正确获取图像的方法是什么?

Any help is appreciated. 任何帮助表示赞赏。
-Thanks -谢谢

Expected output 预期产量

预期产量

Actual output 实际产量

实际产量

if you are only loading an image, I recommend you to use imread instead, also, you will need to specified the second parameter of imread to load the alpha channel too, that is CV_LOAD_IMAGE_UNCHANGED or cv::IMREAD_UNCHANGED , depending on the version (in the worst case a -1 also works). 如果仅加载图像,建议您使用imread代替,同样,还需要指定imread的第二个参数来加载alpha通道,即CV_LOAD_IMAGE_UNCHANGEDcv::IMREAD_UNCHANGED ,具体取决于版本(在最坏的情况是-1也可以)。

As far as I know, the VideoCapture class do not load images/video with a 4th channel. 据我所知, VideoCapture类不会加载第4个通道的图像/视频。 Since you are using a web url, loading the image won't work with imread , but you may use any method to download the data (curl for example) and then use imdecode with the data buffer to get the cv::Mat . 由于您使用的是Web网址,因此无法使用imread加载图像,但可以使用任何方法下载数据(例如,curl),然后将imdecode与数据缓冲区一起使用,以获取cv::Mat OpenCV is a library for image processing, not for downloading images. OpenCV是用于图像处理而非下载图像的库。

If you wanna draw it over another image you can do that: 如果您想将其绘制在另一张图像上,可以执行以下操作:

/**
 * @brief Draws a transparent image over a frame Mat.
 * 
 * @param frame the frame where the transparent image will be drawn
 * @param transp the Mat image with transparency, read from a PNG image, with the IMREAD_UNCHANGED flag
 * @param xPos x position of the frame image where the image will start.
 * @param yPos y position of the frame image where the image will start.
 */
void drawTransparency(Mat frame, Mat transp, int xPos, int yPos) {
    Mat mask;
    vector<Mat> layers;

    split(transp, layers); // seperate channels
    Mat rgb[3] = { layers[0],layers[1],layers[2] };
    mask = layers[3]; // png's alpha channel used as mask
    merge(rgb, 3, transp);  // put together the RGB channels, now transp insn't transparent 
    transp.copyTo(frame.rowRange(yPos, yPos + transp.rows).colRange(xPos, xPos + transp.cols), mask);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM