J'ai essayé de charger des fichiers .png avec un canal de transparence (RGB et Alph) sans succès. Il semble que openCV retire le 4ème canal de l'image. Existe-t-il une méthode pour charger l'image avec les 4 canaux complets, y compris le canal alpha, même si je devais modifier le code source d'OpenCV et le reconstruire?
Si vous utilisez OpenCV 2 ou OpenCV 3, vous devez utiliser les drapeaux IMREAD_ * (comme mentionné à ici ).
C++
using namespace cv;
Mat image = imread("image.png", IMREAD_UNCHANGED);
Python
import cv2
im = cv2.imread("image.png", cv2.IMREAD_UNCHANGED)
Selon la documentation , OpenCV prend en charge le canal alpha sur les PNG.
Appelez simplement la fonction imread en utilisant CV_LOAD_IMAGE_UNCHANGED comme indicateurs comme ceci:
cvLoadImage("file.png", CV_LOAD_IMAGE_UNCHANGED)
La bonne façon de lire un PNG transparent est d'utiliser le 4ème canal comme canal alpha. La plupart du temps, on veut un fond blanc, si c'est le cas, le code ci-dessous peut être utilisé pour la composition 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)
Un blog détaillé à ce sujet est ici ici .
La meilleure façon possible de charger une image png avec les 4 canaux est;
img= cv2.imread('imagepath.jpg',negative value)
Selon la documentation openCV,
Si la valeur de Flag est,
1) = 0 Retourne une image en niveaux de gris.
2) <0 Retourne l'image chargée telle quelle (avec canal alpha).
Si vous voulez dessiner cette image transparente sur une autre image, ouvrez votre image comme répondu par @ satya-mallick, puis utilisez cette méthode:
/**
* @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);
}