Я пытался загрузить файлы .png с каналом прозрачности (RGB и Alph) без удачи. Похоже, что openCV удаляет 4-й канал из изображения. Есть ли способ загрузить изображение с полными 4 каналами, включая альфа-канал, даже если мне пришлось изменить исходный код OpenCV и перестроить его?
Как загрузить PNG изображения с 4 каналами?
Ответ 1
Если вы используете OpenCV 2 или OpenCV 3, вы должны использовать флаги IMREAD_ * (как указано в здесь).
С++
using namespace cv;
Mat image = imread("image.png", IMREAD_UNCHANGED);
Python
import cv2
im = cv2.imread("image.png", cv2.IMREAD_UNCHANGED)
Ответ 2
Согласно документации OpenCV поддерживает альфа-канал в PNG.
Просто вызовите функцию imread с помощью CV_LOAD_IMAGE_UNCHANGED в виде таких флагов:
cvLoadImage("file.png", CV_LOAD_IMAGE_UNCHANGED)
Ответ 3
Правильный способ чтения прозрачного 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)
Подробный блог об этом здесь.
Ответ 4
По-видимому, OpenCV по-прежнему не поддерживает PNG с альфа-каналом.
Есть хаки, чтобы обойти это.
Ответ 5
Самый лучший способ загрузить изображение в формате png со всеми 4 каналами:
img= cv2.imread('imagepath.jpg',negative value)
Согласно документации openCV,
Если значение флага
1) = 0 Возвращает изображение в градациях серого.
2) <0 Вернуть загруженное изображение как есть (с альфа-каналом).
Ответ 6
Если вы хотите нарисовать это прозрачное изображение поверх другого изображения, откройте свое изображение, ответив @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 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);
}