Je poste un code qui va lire un unique YUV 4:2:0 plane fichier image. Vous pouvez appliquer directement à la plupart YUV fichiers (il suffit de garder la lecture à partir de la même FILE objet). Le exception de cela est lorsque vous traitez avec YUV fichiers d'en-tête (en général, ils ont une *.y4m extension). Si vous voulez traiter avec ces fichiers, vous avez deux options:
Écrire votre propre fonction pour consommer les données d'en-tête de la FILE objet avant d'utiliser le code ci-dessous
Bande les en-têtes à partir de *.y4m images (à l'aide de ffmpeg ou un outil similaire). C'est l'option que je préfère car c'est le plus simple.
Il permettra aussi de ne pas travailler pour toute autre forme de format YUV (non-planaire, différents chroma décimation). @Stephane a souligné, il y a de nombreux formats (et la plupart d'entre eux n'ont pas d'identifier les en-têtes), qui est probablement pourquoi OpenCV ne prend pas en charge hors de la boîte.
Mais de travailler avec eux, c'est assez simple:
Commencer avec une image et ses dimensions (ceci est requis lors de la lecture d'un fichier YUV)
Lire la luminance et la chrominance en 3 les images
Haut de gamme chroma images par un facteur de 2 à rémunération pour la chrominance décimation. Note qu'il y a effectivement plusieurs des façons de compenser pour la chrominance décimation. Suréchantillonnage est juste le plus simple
Combiner en YUV image. Si vous voulez RVB, vous pouvez utiliser cvCvtColor.
Enfin, le code:
IplImage *
cvLoadImageYUV(FILE *fin, int w, int h)
{
assert(fin);
IplImage *py = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
IplImage *pu = cvCreateImage(cvSize(w/2,h/2), IPL_DEPTH_8U, 1);
IplImage *pv = cvCreateImage(cvSize(w/2,h/2), IPL_DEPTH_8U, 1);
IplImage *pu_big = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
IplImage *pv_big = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
IplImage *image = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 3);
IplImage *result = NULL;
assert(py);
assert(pu);
assert(pv);
assert(pu_big);
assert(pv_big);
assert(image);
for (int i = 0; i < w*h; ++i)
{
int j = fgetc(fin);
if (j < 0)
goto cleanup;
py->imageData[i] = (unsigned char) j;
}
for (int i = 0; i < w*h/4; ++i)
{
int j = fgetc(fin);
if (j < 0)
goto cleanup;
pu->imageData[i] = (unsigned char) j;
}
for (int i = 0; i < w*h/4; ++i)
{
int j = fgetc(fin);
if (j < 0)
goto cleanup;
pv->imageData[i] = (unsigned char) j;
}
cvResize(pu, pu_big, CV_INTER_NN);
cvResize(pv, pv_big, CV_INTER_NN);
cvMerge(py, pu_big, pv_big, NULL, image);
result = image;
cleanup:
cvReleaseImage(&pu);
cvReleaseImage(&pv);
cvReleaseImage(&py);
cvReleaseImage(&pu_big);
cvReleaseImage(&pv_big);
if (result == NULL)
cvReleaseImage(&image);
return result;
}
J'ai le même Problème, maintenant, je suis en train d'ouvrir et de travailler avec une vidéo qui a UYVY(4:2:2) comme codec , j'ai essayé de vous code mais il ne fonctionne pas je sais que vous avez mentionné dans votre réponse, mais pouvez-vous dire pourquoi ?? merci d'avance pour votre aide Le code que j'ai posté poignées YUV 4:2:0. Depuis votre vidéo est en YUV 4:2:2 , mon code sera certainement pas de travailler sur votre vidéo directement. Vous devrez adapter le code pour gérer votre format. Pour plus de détails, voir: en.wikipedia.org/wiki/Chroma_subsampling#4:2:2
Je ne pense pas que c'est possible de le faire, au moins avec la version actuelle. Bien sûr, il ne serait pas difficile à faire, mais ce n'est pas une caractéristique intéressante, comme:
OpenCV travaille habituellement sur webcam stream, qui sont au format RGB, ou sur codé fichiers, qui sont directement décodé en RVB à des fins d'affichage ;
OpenCV est dédié à la Vision par Ordinateur, où YUV est une commune de moins de format que dans le Codage de la communauté, par exemple ;
il ya beaucoup de différents formats YUV, ce qui impliquerait beaucoup de travail à mettre en œuvre.
Les Conversions sont toujours possibles, même si, à l'aide de cvCvtColor(), ce qui signifie qu'il est de l'intérêt de toute façon.
J'ai rencontré le même problème. Ma solution est
1. lire un yuv image (comme I420) à un objet de type string "yuv".
2. convertir le yuv cadre de BGR24 format. J'utilise libyuv de le faire. Il est facile d'écrire un wrapper python pour libyuv fonctions. maintenant, vous obtenez un autre objet de type string "bgr" avec BGR24 format.
3. utilisation de numpy.fromstring pour obtenir l'image de l'objet à partir de la "bgr" objet de type string. vous avez besoin de changer la forme de l'objet image.
Ci-dessous est un simple yuv viewer pour votre référence.
import cv2
# below is the extension wrapper for libyuv
import yuvtorgb
import numpy as np
f = open('i420_cif.yuv', 'rb')
w = 352
h = 288
size = 352*288*3/2
while True:
try:
yuv = f.read(size)
except:
break
if len(yuv) != size:
f.seek(0, 0)
continue
bgr = yuvtorgb.i420_to_bgr24(yuv, w, h)
img = np.fromstring(bgr, dtype=np.uint8)
img.shape = h,w,3
cv2.imshow('img', img)
if cv2.waitKey(50) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
J'ai écrit un code python pour lire YUV NV21 flux à partir d'un fichier binaire.
OriginalL'auteur xianyanlin
Comme mentionné précédemment, il existe de NOMBREUX types de formats YUV:
http://www.fourcc.org/yuv.php
Pour convertir RVB à partir d'un format YUV dans OpenCV est très simple:
Voici un exemple pour une YUV tampon dans YV12 format:
La clé astuce consiste à définir les dimensions de votre RVB Mat avant vous convertir.
OriginalL'auteur Aaron Becker
Mise à JOUR il y a une version plus récente du code ici: https://github.com/chelyaev/opencv-yuv
Je poste un code qui va lire un unique YUV 4:2:0 plane fichier image. Vous pouvez appliquer directement à la plupart YUV fichiers (il suffit de garder la lecture à partir de la même
FILE
objet). Le exception de cela est lorsque vous traitez avec YUV fichiers d'en-tête (en général, ils ont une*.y4m
extension). Si vous voulez traiter avec ces fichiers, vous avez deux options:FILE
objet avant d'utiliser le code ci-dessousffmpeg
ou un outil similaire). C'est l'option que je préfère car c'est le plus simple.Il permettra aussi de ne pas travailler pour toute autre forme de format YUV (non-planaire, différents chroma décimation). @Stephane a souligné, il y a de nombreux formats (et la plupart d'entre eux n'ont pas d'identifier les en-têtes), qui est probablement pourquoi OpenCV ne prend pas en charge hors de la boîte.
Mais de travailler avec eux, c'est assez simple:
cvCvtColor
.Enfin, le code:
Le code que j'ai posté poignées YUV 4:2:0. Depuis votre vidéo est en YUV 4:2:2 , mon code sera certainement pas de travailler sur votre vidéo directement. Vous devrez adapter le code pour gérer votre format. Pour plus de détails, voir: en.wikipedia.org/wiki/Chroma_subsampling#4:2:2
OriginalL'auteur mpenkov
Je ne pense pas que c'est possible de le faire, au moins avec la version actuelle. Bien sûr, il ne serait pas difficile à faire, mais ce n'est pas une caractéristique intéressante, comme:
Les Conversions sont toujours possibles, même si, à l'aide de
cvCvtColor()
, ce qui signifie qu'il est de l'intérêt de toute façon.OriginalL'auteur Stéphane Péchard
J'ai rencontré le même problème. Ma solution est
1. lire un yuv image (comme I420) à un objet de type string "yuv".
2. convertir le yuv cadre de BGR24 format. J'utilise libyuv de le faire. Il est facile d'écrire un wrapper python pour libyuv fonctions. maintenant, vous obtenez un autre objet de type string "bgr" avec BGR24 format.
3. utilisation de numpy.fromstring pour obtenir l'image de l'objet à partir de la "bgr" objet de type string. vous avez besoin de changer la forme de l'objet image.
Ci-dessous est un simple yuv viewer pour votre référence.
OriginalL'auteur Yi Wang