简体   繁体   中英

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.
I'm reading the image from an URL using video capture. 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. What is the way to preserve alpha channel and get the image correctly?

Any help is appreciated.
-Thanks

预期产量

实际产量

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).

As far as I know, the VideoCapture class do not load images/video with a 4th channel. 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 . OpenCV is a library for image processing, not for downloading images.

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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