简体   繁体   English

如何加载具有 4 个通道的 png 图像?

[英]How to load png images with 4 channels?

I have been trying to load.png files with transparency channel (RGB and Alph) with no luck.我一直在尝试使用透明通道(RGB 和 Alph)加载 .png 文件,但没有成功。 It appears that openCV strips the 4th channel out of the image.看起来 openCV 从图像中剥离了第 4 个通道。 Is there any method to load the image with the complete 4 channels including the alpha channel even if I had to modify the OpenCV source code and rebuild it?即使我必须修改 OpenCV 源代码并重建它,是否有任何方法可以加载包含 alpha 通道的完整 4 个通道的图像?

If you are using OpenCV 2 or OpenCV 3 you should use IMREAD_* flags (as mentioned at here ).如果你正在使用OpenCV的2或3的OpenCV你应该使用IMREAD_ *标志(截至提到 这里)。

C++ C++

using namespace cv;
Mat image = imread("image.png", IMREAD_UNCHANGED);

Python蟒蛇

import cv2
im = cv2.imread("image.png", cv2.IMREAD_UNCHANGED)

According to the documentation , OpenCV supports alpha channel on PNGs.根据文档,OpenCV 支持 PNG 上的 alpha 通道。

Just call the imread function using CV_LOAD_IMAGE_UNCHANGED as flags like this:只需使用 CV_LOAD_IMAGE_UNCHANGED 作为标志调用 imread 函数,如下所示:

cvLoadImage("file.png", CV_LOAD_IMAGE_UNCHANGED)

The right way to read a transparent PNG is to use the 4th channel as alpha channel.读取透明 PNG 的正确方法是使用第 4 个通道作为 alpha 通道。 Most of the times one wants a white background, if that is the case then below code can be used for alpha compositing.大多数时候人们想要白色背景,如果是这种情况,那么下面的代码可用于 alpha 合成。

def read_transparent_png(filename):
    image_4channel = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
    alpha_channel = image_4channel[:,:,3]
    rgb_channels = image_4channel[:,:,:3]

    # White Background Image
    white_background_image = np.ones_like(rgb_channels, dtype=np.uint8) * 255

    # Alpha factor
    alpha_factor = alpha_channel[:,:,np.newaxis].astype(np.float32) / 255.0
    alpha_factor = np.concatenate((alpha_factor,alpha_factor,alpha_factor), axis=2)

    # Transparent Image Rendered on White Background
    base = rgb_channels.astype(np.float32) * alpha_factor
    white = white_background_image.astype(np.float32) * (1 - alpha_factor)
    final_image = base + white
    return final_image.astype(np.uint8)

A detailed blog on this is here here .关于此的详细博客在这里

If you wanna draw this transparent image over another image, open your image as answered by @satya-mallick (mode IMREAD_UNCHANGED), then use this method to draw the image over a frame Mat:如果您想在另一个图像上绘制此透明图像,请按照@satya-mallick(模式 IMREAD_UNCHANGED)的回答打开您的图像,然后使用此方法在框架 Mat 上绘制图像:

/**
 * @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 best possible way to load a png image with all 4 channels is ;加载具有所有 4 个通道的 png 图像的最佳方法是;

img= cv2.imread('imagepath.jpg',negative value)

As per openCV documentation,根据 openCV 文档,
If Flag value is,如果 Flag 值是,
1) =0 Return a grayscale image. 1) =0 返回灰度图像。
2) <0 Return the loaded image as is (with alpha channel). 2) <0 按原样返回加载的图像(带有 alpha 通道)。

you can use:您可以使用:

import matplotlib.image as mpimg


img=mpimg.imread('image.png')
plt.imshow(img)

in my case it was the filename extension that caused problems.在我的例子中,是文件扩展名导致了问题。 Check whether your png is a png or something else;)检查您的 png 是 png 还是其他东西;)

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

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