GeckoGeek.fr

Paradigme d'un lézard

Jeudi 19 Octobre 2017

Afficher une Image à Fond Transparent sous OpenCV

Par Lya le 30/03/2010 dans Programmation | 3 commentaires

OpenCV ne gère pas le canal alpha des images qui sont importées. Voici une astuce qui vous permet d’afficher vos images avec un fond transparent comme si elles avaient un canal alpha.

Principe

L’idée est d’ajouter une couleur qui représentera le canal alpha (la plus éloignée possible des couleurs du contour de l’image et non présente dans cette dernière). Après avoir importé cette image, on crée un masque qui correspond à la couleur rajoutée. Et quand on affiche notre image, on applique ce masque.

Cette méthode donne de plutôt bons résultats. Attention par contre d’utiliser une compression sans perte pour votre image, et effectuer vos changement de taille avant de mettre la couleur de fond (sinon vos pixels de contours seront mélangés avec les pixels du fond).


Pratique

Nous supposons que vous avez rajouté votre couleur de fond. Pour nous ce sera du bleu RGB(0, 0, 255).

Tout d’abord, il faut importer l’image :

IplImage *imagePNG;
imagePNG = cvLoadImage("/path/to/your/picture/image.png");

Ensuite, nous créons le masque. Il a la même taille que notre image mais seulement un seul canal (0 à 255).

IplImage *mask;
mask = cvCreateImage(cvGetSize(image), 8, 1);

Nous souhaitons masquer le bleu (0, 0, 255). Nous allons créer un petit intervalle autour de cette couleur pour être sûrs de récupérer tous les pixels près des bords de l’image.

Si nous mettons une tolérance de 130, nous allons récupérer tous les pixels compris entre :
0 <= Rpixel < 130 && 0 <= Gpixel < 130 && 125 <= Bpixel <= 255

Cela s’écrit ainsi en OpenCV (n’oubliez pas que l’image est en BGR, les canaux bleu et rouge sont inversés) :

cvInRangeS(image, cvScalar(125.0, 0.0, 0.0), cvScalar(255.0 + 1.0, 130.0, 130.0), mask);

Tous les pixels qui vérifient l’expression sont mis à 1 (255) dans le masque, et à 0 sinon.

Maintenant, nous inversons le masque (0 => 1, 1 => 0) car nous voulons cacher cette couleur, et montrer le reste (ce qui est à 0 est caché).

cvNot(mask, mask);

Il ne vous reste qu’à afficher votre image en utilisant ce masque par dessus votre vidéo par exemple. Ici on ajoute l’image png à la frame de la vidéo. On établie une région d’intérêt (ROI) afin de pouvoir la positionner où nous le souhaitons sur la frame :

cvSetImageROI(image, cvRect(100, 100, imagePNG->width, imagePNG->height));
cvCopy(imagePNG, image, mask);
cvResetImageROI(image);

Et enfin, on affiche le tout :

cvShowImage("GeckoGeek Image PNG & Transparence", image);

Tout en un

#include "opencv/highgui.h"
#include "opencv/cv.h"

#include
#include
#include 

IplImage* createMask(IplImage* image) {

	IplImage *mask;

	mask = cvCreateImage(cvGetSize(image), 8, 1);

	cvInRangeS(image, cvScalar(125.0, 0.0, 0.0), cvScalar(255.0 + 1.0, 130.0, 130.0), mask);
	cvNot(mask, mask);

	return mask;

}

int main() {

	// Image & hsvImage
	IplImage *image, *imagePNG, *mask;
	// Video Capture
	CvCapture *capture;
	// Key for keyboard event
	char key;

	// Import png image
	imagePNG = cvLoadImage("/path/to/your/picture/image.png");

	mask = createMask(imagePNG);

	// Initialize the video Capture (200 => CV_CAP_V4L2)
 	capture = cvCreateCameraCapture(200);

	// Check if the capture is ok
    	if (!capture) {
		printf("Can't initialize the video capture.\n");
        	return -1;
 	}

	// Create the windows
   	cvNamedWindow("GeckoGeek Image PNG & Transparence", CV_WINDOW_AUTOSIZE);

	// While we don't want to quit
	while(key != 'Q' && key != 'q') {

		// We get the current image
		image = cvQueryFrame(capture);

		// If there is no image, we exit the loop
		if(!image)
			continue;

		cvSetImageROI(image, cvRect(100, 100, imagePNG->width, imagePNG->height));
		cvCopy(imagePNG, image, mask);
		cvResetImageROI(image);

		cvShowImage("GeckoGeek Image PNG & Transparence", image);

		// We wait 10 ms
		key = cvWaitKey(10);

	}

	// Destroy the window we have created
	cvDestroyWindow("GeckoGeek Image PNG & Transparence");

	// Destroy the mask
	cvReleaseImage(&mask);

	// Destroy the capture
	cvReleaseCapture(&capture);

	return -1;
}
Commentaires (3)
  1. Jung Eun Kwon le 23 May 2010 à 12:53

    hi, my name is JungEun Kwon ,and i’m korean.
    I’m now studing openCV and then I read your text..
    first of all, I can’t speak both English and France very well…
    umm… anyway, I have one problem… my program can’t apply alpha method.
    you know, in your text, there are 2 pictures. one is applied alpha and another is not applied alpha. how can you solve this problem?
    what’s method that you are using?
    I hope you to send me a e-mail at deungeuni@naver.com

    thank you.^^

  2. Lya le 25 May 2010 à 09:58

    Hi,

    I will try to see this with you by mail.
    Anyway, OpenCV’s images have a sort of alpha canal, but it doesn’t accept the alpha canal of existing images (such as png files).
    So in this example, we take an image with a (flashy) color in background (that stand at the place of the alpha canal) and then in the OpenCV program we create a mask on this color. In this mask, the pixels with the flashy color have a 0 value, and all the other have a 1 value. So when we show the image and apply the mask, the pixels that have a correspondant 0 value won’t be show (the flashy colored ones) and those with a correspondant 1 value will be show (basically, your image). Then it’s as if we got an alpha channel.

    Hope it helps 😉

  3. DJEASSITTARAME le 28 Nov 2015 à 22:33

    Bonjour, je souhaiterais savoir si il y a une commande spécifique a taper sur linux ubuntu 14 pour faire fonctionner le code s’il vous plait

    Cordialement DJEASSITTARAME Christophe


Laisser un commentaire