Corriger YUV422 de conversion RGB
J'ai essayé de s'attaquer à un YUV422 dans une conversion RGB problème pendant environ une semaine. J'ai visité de nombreux sites différents et ont obtenu des formules différentes de chacun. Si quelqu'un a des suggestions, je serais heureux d'entendre parler d'eux. Les formules ci-dessous donne-moi une image avec soit et de l'ensemble de violet ou une teinte verte. En ce moment je n'ai pas été en mesure de trouver une formule qui me permet de retrouver une bonne image RVB. J'ai inclure toutes mes différents morceaux de code ci-dessous.
//for(int i = 0; i < 1280 * 720 * 3; i=i+3)
//{
// /*m_RGB->imageData[i] = pData[i] + pData[i+2]*((1 - 0.299)/0.615);
// m_RGB->imageData[i+1] = pData[i] - pData[i+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[i+2]*((0.299*(1 - 0.299))/(0.615*0.587));
// m_RGB->imageData[i+2] = pData[i] + pData[i+1]*((1 - 0.114)/0.436);*/
// m_RGB->imageData[i] = pData[i] + 1.403 * (pData[i+1] - 128);
// m_RGB->imageData[i+1] = pData[i] + 0.344 * (pData[i+1] - 128) - 0.714 * (pData[i+2] - 128);
// m_RGB->imageData[i+2] = pData[i] + 1.773 * (pData[i+2] - 128);
//}
for(int i = 0, j=0; i < 1280 * 720 * 3; i+=6, j+=4)
{
/*m_RGB->imageData[i] = pData[j] + pData[j+3]*((1 - 0.299)/0.615);
m_RGB->imageData[i+1] = pData[j] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587));
m_RGB->imageData[i+2] = pData[j] + pData[j+1]*((1 - 0.114)/0.436);
m_RGB->imageData[i+3] = pData[j+2] + pData[j+3]*((1 - 0.299)/0.615);
m_RGB->imageData[i+4] = pData[j+2] - pData[j+1]*((0.114*(1-0.114))/(0.436*0.587)) - pData[j+3]*((0.299*(1 - 0.299))/(0.615*0.587));
m_RGB->imageData[i+5] = pData[j+2] + pData[j+1]*((1 - 0.114)/0.436);*/
/*m_RGB->imageData[i] = pData[j] + 1.403 * (pData[j+3] - 128);
m_RGB->imageData[i+1] = pData[j] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128);
m_RGB->imageData[i+2] = pData[j] + 1.773 * (pData[j+1] - 128);
m_RGB->imageData[i+3] = pData[j+2] + 1.403 * (pData[j+3] - 128);
m_RGB->imageData[i+4] = pData[j+2] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128);
m_RGB->imageData[i+5] = pData[j+2] + 1.773 * (pData[j+1] - 128);*/
BYTE Cr = pData[j+3] - 128;
BYTE Cb = pData[j+1] - 128;
/*m_RGB->imageData[i] = pData[j] + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
m_RGB->imageData[i+1] = pData[j] - ((Cb >> 2) + (Cb >> 4) + (Cb >> 5)) - ((Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5));
m_RGB->imageData[i+2] = pData[j] + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
m_RGB->imageData[i+3] = pData[j+2] + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
m_RGB->imageData[i+4] = pData[j+2] - ((Cb >> 2) + (Cb >> 4) + (Cb >> 5)) - ((Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5));
m_RGB->imageData[i+5] = pData[j+2] + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);*/
/*int R1 = clamp(1 * pData[j] + 0 * Cb + 1.4 * Cr, 0, 255), R2 = clamp(1 * pData[j+2] + 0 * Cb + 1.4 * Cr, 0, 255);
int G1 = clamp(1 * pData[j] - 0.343 * Cb - 0.711 * Cr, 0, 255), G2 = clamp(1 * pData[j+2] - 0.343 * Cb - 0.711 * Cr, 0, 255);
int B1 = clamp(1 * pData[j] + 1.765 * Cb + 0 * Cr, 0, 255), B2 = clamp(1 * pData[j+2] + 1.765 * Cb + 0 * Cr, 0, 255);*/
/*int R1 = clamp(pData[j] + 1.403 * (pData[j+3] - 128), 0, 255), R2 = clamp(pData[j+2] + 1.403 * (pData[j+3] - 128), 0, 255);
int G1 = clamp(pData[j] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128), 0, 255), G2 = clamp(pData[j+2] + 0.344 * (pData[j+1] - 128) - 0.714 * (pData[j+3] - 128), 0, 255);
int B1 = clamp(pData[j] + 1.773 * (pData[j+1] - 128), 0, 255), B2 = clamp(pData[j+2] + 1.773 * (pData[j+1] - 128), 0, 255);*/
int R1 = clamp((298 * (pData[j] - 16) + 409 * (pData[j+3] - 128) + 128) >> 8, 0, 255), R2 = clamp((298 * (pData[j+2] - 16) + 409 * (pData[j+3] - 128) + 128) >> 8, 0, 255);
int G1 = clamp((298 * (pData[j] - 16) - 100 * (pData[j+1] - 128) - 208 * (pData[j+3] - 128) + 128) >> 8, 0, 255), G2 = clamp((298 * (pData[j+2] - 16) - 100 * (pData[j+1] - 128) - 208 * (pData[j+3] - 128) + 128) >> 8, 0, 255);
int B1 = clamp((298 * (pData[j] - 16) + 516 * (pData[j+1] - 128) + 128) >> 8, 0, 255), B2 = clamp((298 * (pData[j+2] - 16) + 516 * (pData[j+1] - 128) + 128) >> 8, 0, 255);
//printf("R: %d, G: %d, B: %d, R': %d, G': %d, B': %d \n", R1, G1, B1, R2, G2, B2);
m_RGB->imageData[i] = (char)R1;
m_RGB->imageData[i+1] = (char)G1;
m_RGB->imageData[i+2] = (char)B1;
m_RGB->imageData[i+3] = (char)R2;
m_RGB->imageData[i+4] = (char)G2;
m_RGB->imageData[i+5] = (char)B2;
/*m_RGB->imageData[i] = (char)(clamp(1.164 * (pData[j] - 16) + 1.793 * (Cr), 0, 255));
m_RGB->imageData[i+1] = (char)(clamp(1.164 * (pData[j] - 16) - 0.534 * (Cr) - 0.213 * (Cb), 0, 255));
m_RGB->imageData[i+2] = (char)(clamp(1.164 * (pData[j] - 16) + 2.115 * (Cb), 0, 255));
m_RGB->imageData[i+3] = (char)(clamp(1.164 * (pData[j+2] - 16) + 1.793 * (Cr), 0, 255));
m_RGB->imageData[i+4] = (char)(clamp(1.164 * (pData[j+2] - 16) - 0.534 * (Cr) - 0.213 * (Cb), 0, 255));
m_RGB->imageData[i+5] = (char)(clamp(1.164 * (pData[j+2] - 16) + 2.115 * (Cb), 0, 255));*/
}
Toute aide est grandement appréciée.
Quelle est la source de l'YUV données, et quelle est la destination? Par exemple, si la destination est Windows, vous devez utiliser BGR ordre plutôt que de RVB.
le YUV est à venir à partir d'un Decklink Intensité Pro carte de capture. J'ai aussi essayé de faire basculer le BGR/valeurs RVB et il n'a pas aidé. Ce qui est fait sur une zone de Windows
Si vous utilisez la decklink SDK, pourquoi ne pas vous utilisez simplement la ConvertFrame méthode qui est une partie de l'API?
Il me semble que vous confondez Cr avec Cb, vous devriez changer de place.
J'ai essayé d'utiliser ConvertFrame, mais il renvoie une erreur lorsque je l'utilise. j'ai contacté DeckLink et ils ont dit qu'YUV RVB conversions sont actuellement pas pris en charge
le YUV est à venir à partir d'un Decklink Intensité Pro carte de capture. J'ai aussi essayé de faire basculer le BGR/valeurs RVB et il n'a pas aidé. Ce qui est fait sur une zone de Windows
Si vous utilisez la decklink SDK, pourquoi ne pas vous utilisez simplement la ConvertFrame méthode qui est une partie de l'API?
Il me semble que vous confondez Cr avec Cb, vous devriez changer de place.
J'ai essayé d'utiliser ConvertFrame, mais il renvoie une erreur lorsque je l'utilise. j'ai contacté DeckLink et ils ont dit qu'YUV RVB conversions sont actuellement pas pris en charge
OriginalL'auteur Seb | 2011-11-07
Vous devez vous connecter pour publier un commentaire.
Quelques indices pour vous aider:
Vous êtes confus Cr avec Cb.
En supposant UYVY/422
Votre calcul de conversion sont bizarre, et incorrectes pour la HD.
Pour SD
Pour la HD
Vous pouvez simplement utiliser
ConvertFrame
qui est une partie de la Decklink SDK.OriginalL'auteur ronag
Votre problème, c'est qu'il y a beaucoup de YUV422 formats. Vous devez trouver le montant exact (le FOURCC indice pour la vidéo que vous utilisez), et puis trouver la bonne façon de le décoder.
Ce que vous pouvez faire est d'enregistrer une vidéo à partir de votre conseil, de l'ouvrir dans VLC, et de regarder le Codec détails pour trouver l'exacte FOURCC utilisé.
http://www.fourcc.org/yuv.php
OriginalL'auteur Sam
En supposant paniers 422 je ne vois pas l'un de vos blocs d'échantillonnage de l'entrée de données correctement. Dans les paniers 422 les données d'entrée vont Y1U1Y2V1 Y3U2Y4V2 où l'image globale est un Y (luminance) de l'image à pleine résolution et un pour chacun de U et V de chacun à la moitié de la résolution horizontale.
Ici est là que j'ai commencer: Décompresser l'alternance de valeurs d'entrée et d'en extraire une image en niveaux de gris:
Une fois que vous avez réglé pour produire une image en niveaux de gris puis d'introduire U et V en regardant
pData[j+1]
etpData[j+3]
(ou, sur la même pixels,pData[j-1]
etpData[j+1]
). Simplifier c'est pourquoi certains algorithmes de faire deux YUV pixels à la fois.Quand que travaux considèrent l'extraction de l'U et V des images et correctement rééchantillonnage à pleine résolution pour produire un 444 image. Simple duplication de U et V pour les pixels adjacents est comme upscaling par la duplication de pixels.
(Notez que d'autres arrangements comme des 420 ont compliqué encore plus la co-implantation)
OriginalL'auteur Ben Jackson
J'ai aussi eu du mal avec la conversion
u
etv
sontsbyte
, ety
est juste unbyte
.C'était la version correcte
OriginalL'auteur Jo VdB