Pages : 1
#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?
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
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
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
Hors ligne