Как загрузить PNG изображения с 4 каналами? - PullRequest
29 голосов
/ 27 сентября 2010

Я пытался загрузить файлы .png с каналом прозрачности (RGB и Alph), но безуспешно. Похоже, что openCV удаляет 4-й канал из изображения. Есть ли способ загрузить изображение с полными 4 каналами, включая альфа-канал, даже если мне пришлось изменить исходный код OpenCV и перестроить его?

Ответы [ 5 ]

51 голосов
/ 09 апреля 2015

Если вы используете OpenCV 2 или OpenCV 3, вы должны использовать флаги IMREAD_ * (как указано здесь ).

C ++

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

Python

import cv2
im = cv2.imread("image.png", cv2.IMREAD_UNCHANGED)
12 голосов
/ 12 мая 2013

Согласно документации , OpenCV поддерживает альфа-канал в PNG.

Просто вызовите функцию imread, используя CV_LOAD_IMAGE_UNCHANGED в качестве флагов, подобных этому:

cvLoadImage("file.png", CV_LOAD_IMAGE_UNCHANGED)
7 голосов
/ 27 января 2017

Правильный способ чтения прозрачного PNG - использовать 4-й канал в качестве альфа-канала.В большинстве случаев вам нужен белый фон, если это так, то приведенный ниже код можно использовать для альфа-композиции.

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)

Подробный блог об этом здесь здесь .

1 голос
/ 08 марта 2019

Лучший способ загрузить изображение в формате png со всеми 4 каналами:

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

Согласно документации openCVЕсли значение флага1) = 0 Возвращает изображение в градациях серого.2) <0 Возвращает загруженное изображение как есть (с альфа-каналом). </p>

0 голосов
/ 15 апреля 2019

Если вы хотите нарисовать это прозрачное изображение поверх другого изображения, откройте свое изображение, ответив @ satya-mallick, затем используйте этот метод:

/**
 * @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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...