Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/07/2008, à 12:52

Glove

Conversion video RGB24 > YUV420P

Bonjour,

J'ai un gros souci avec une acquisition video sous Linux en c++ depuis une webcam.

L'image recue est en rgb24, et la librairie que j'utilise (EMIPLIB) ne gere que le YUV420P.

Comment puis-je effectuer une conversion de ma source rgb24 au format yuv420p ?

Voici un bout du code en question :

struct video_picture pic;

        if (pic.palette == VIDEO_PALETTE_YUV420P)
	{
		subtype = MIPRAWVIDEOMESSAGE_TYPE_YUV420P;

		int w2 = m_width;
		int h2 = m_height;
		
		if (w2&1) w2++;
		if (h2&1) h2++;
		
		allocSize = (w2*h2*3)/2;

	}  else if (pic.palette == VIDEO_PALETTE_RGB24) {
	
	        ::close(m_device);
		m_device = -1;
		printf("VIDEO_PALETTE_RGB24\n");
		setErrorString(MIPV4LINPUT_ERRSTR_CANTUNDERSTANDPALETTE);
		return false;
		
	}

Avec ma source de la camera, j'obtiens donc le cas VIDEO_PALETTE_RGB24 qui entraine une erreur.

J'ai trouve plusieurs algoithmes permettant de passer de RGB24 en YUV420P, mais la structure de mon image semble inadapte a ces formules.

Apres qques recherches, il semblerait que la structure de l'image soit :

struct video_picture
{
	__u16	brightness;
	__u16	hue;
	__u16	colour;
	__u16	contrast;
	__u16	whiteness;	/* Black and white only */
	__u16	depth;  /* Capture depth */
	__u16   palette;	/* Palette in use */
#define VIDEO_PALETTE_GREY	1	/* Linear greyscale */
#define VIDEO_PALETTE_HI240	2	/* High 240 cube (BT848) */
#define VIDEO_PALETTE_RGB565	3	/* 565 16 bit RGB */
#define VIDEO_PALETTE_RGB24	4	/* 24bit RGB */
#define VIDEO_PALETTE_RGB32	5	/* 32bit RGB */
#define VIDEO_PALETTE_RGB555	6	/* 555 15bit RGB */
#define VIDEO_PALETTE_YUV422	7	/* YUV422 capture */
#define VIDEO_PALETTE_YUYV	8
#define VIDEO_PALETTE_UYVY	9	/* The great thing about standards is ... */
#define VIDEO_PALETTE_YUV420	10
#define VIDEO_PALETTE_YUV411	11	/* YUV411 capture */
#define VIDEO_PALETTE_RAW	12	/* RAW capture (BT848) */
#define VIDEO_PALETTE_YUV422P	13	/* YUV 4:2:2 Planar */
#define VIDEO_PALETTE_YUV411P	14	/* YUV 4:1:1 Planar */
#define VIDEO_PALETTE_YUV420P	15	/* YUV 4:2:0 Planar */
#define VIDEO_PALETTE_YUV410P	16	/* YUV 4:1:0 Planar */
#define VIDEO_PALETTE_PLANAR	13	/* start of planar entries */
#define VIDEO_PALETTE_COMPONENT 7	/* start of component entries */
};

Comment transformer une image de ce type etant en RGB24 en une autre image de ce type, en YUV420P ?

Enfin, une derniere question : YUV420P et YV12, c'est pareil ?
Je trouve souvent des docs mettant les deux dans le meme sac...


Glove

Hors ligne

#2 Le 14/07/2008, à 18:37

robrob

Re : Conversion video RGB24 > YUV420P

Bon c'est facile, dans le cas du rgb24:

allocSize = m_width*m_height*3;

Quelle est la suite? lol

La conversion d'image RGB24 en YUV240P ne doit pas poser de problème (c'est qu'un bête calcul après tout), il faut juste savoir le format de l'entrée (d'où viennent m_width, m_height, où sont les données de l'image?) et ce qui est nécessaire en sortie (la structure video_picture ne contient visiblement pas les données de l'image).

Sinon pour la question sur le format, c'est très bien expliqué sur wikipedia:
http://en.wikipedia.org/wiki/YUV

The Y'V12 format is essentially the same as Y'UV420p, but it has the U and V data reversed

Hors ligne

#3 Le 15/07/2008, à 05:37

Glove

Re : Conversion video RGB24 > YUV420P

Merci pour ta reponse !

OK pour le allocSize.
Effectivement, les donnes brutes ne me semblent pas stockees ici...
Mais n'y a-t-il pas d'autres parametres a changer que le allocSize ?

Par exemple, j'ai tente un petit affichage des valeurs de pic pour mon cas, et j'obtiens :
colour = 32768
hue = 0
brigthness = 0
contrast = 16128
whiteness = 0
depth = 24

La profondeur n'est pas de 12 (au lieu de 24) en YUV420P ?

Ensuite, m_width et m_weight viennent de la :

	struct video_window win;

	if (ioctl(m_device,VIDIOCGWIN,&win) == -1)
	{
		::close(m_device);
		m_device = -1;
		setErrorString(MIPV4LINPUT_ERRSTR_CANTGETWINDOWINFO);
		return false;
	}
	
	m_width = win.width;
	m_height = win.height;

Et voila le code complet original commente :
fichier : http://code.google.com/p/imcsproject/source/browse/trunk/emiplib/mipv4linput.cpp?r=10
doc : http://research.edm.uhasselt.be/emiplib/documentation/classMIPV4LInput.html

J'ai effectivement trouve quelques formules de conversion, mais je ne sais pas trop ou les appliquer...

En tout cas, merci de votre aide wink

Dernière modification par Glove (Le 15/07/2008, à 05:38)


Glove

Hors ligne

#4 Le 16/07/2008, à 12:31

robrob

Re : Conversion video RGB24 > YUV420P

J'ai regardé rapidement et je ne suis pas sûr d'avoir compris ce que faisait le code.

Toutefois, il me semble que le plus constructif serait de modifier EMIPLIB pour y ajouter le support du RGB24, à priori en dérivant la classe MIPVideoMessage.
C'est alors cette nouvelle classe qui s'occuperait de la conversion RGB24 -> YUV420P.

Hors ligne

#5 Le 17/07/2008, à 02:46

Glove

Re : Conversion video RGB24 > YUV420P

Ouais, effectivement, j'en suis arrive a cette conclusion.

En fait faudrait carrement changer la classe MIPRawYUV420PMessage (qui derive de MIPVideoMessage) en une classe abstraite MIPRawVideoMessage qui pourrait alors etre MIPRawYUV420PMessage ou MIPRawRGB24Message.

Mais ca demande de modifier entierement tout le code, car il faut alors pouvoir traiter les YUV420P et les RGB24 aux etapes de codage / decodage...

N'ayant pas la motivation pour faire cela, je m'attaque a la lourde librairie libvlc en esperant pouvoir l'utiliser comme je le souhaite wink


Merci pour l'aide en tout cas !


Glove

Hors ligne

#6 Le 18/07/2008, à 06:30

robrob

Re : Conversion video RGB24 > YUV420P

Pour faire les conversions de format vidéo tu as aussi la bibli swscale qui fait parti de ffmpeg. Ceci dit, pour avoir juste une conversion RGB24 -> YUV420P, ça me semble un peu bourrin.

Note que tu n'as pas besoin d'implémenter le décodage car ce qui t'intéresse c'est surtout pouvoir utiliser EMIPLIB avec un flux RGB24 en entrée, pas d'en avoir en sorti wink

Hors ligne