YUV 4: 2: 0 plan ressemble à ceci:
----------------------
| Y | Cb|Cr |
----------------------
où:
Y = width x height pixels
Cb = Y/4 pixels
Cr = Y/4 pixels
Total num pixels (bytes) = width * height * 3/2
Et le subsamling utilisé comme ceci:
Cela signifie que chaque valeur chroma-pixel est partagée entre 4 luma-pixels. Une approche consiste simplement à supprimer des pixels, en s'assurant que la relation Y-Cb-Cr correspondante est conservée/recalculée.
Quelque chose proche du Nearest-neighbor interpolation mais inversé.
Une autre approche est d'abord convertir 4: 2: 0 à 4 sous-échantillonnage: 4: 4
Ici, vous avez 1 à 1 entre les données luma et chroma.
C'est la bonne façon d'interpoler la chrominance entre 4: 2: 0 et 4: 2: 2 (la luma est déjà à la résolution correcte) Code en python, suivez le lien html pour c-dito. Le code n'est pas très pythonique, juste une traduction directe de la version c.
def __conv420to422(self, src, dst):
"""
420 to 422 - vertical 1:2 interpolation filter
Bit-exact with
http://www.mpeg.org/MPEG/video/mssg-free-mpeg-software.html
"""
w = self.width >> 1
h = self.height >> 1
for i in xrange(w):
for j in xrange(h):
j2 = j << 1
jm3 = 0 if (j<3) else j-3
jm2 = 0 if (j<2) else j-2
jm1 = 0 if (j<1) else j-1
jp1 = j+1 if (j<h-1) else h-1
jp2 = j+2 if (j<h-2) else h-1
jp3 = j+3 if (j<h-3) else h-1
pel = (3*src[i+w*jm3]
-16*src[i+w*jm2]
+67*src[i+w*jm1]
+227*src[i+w*j]
-32*src[i+w*jp1]
+7*src[i+w*jp2]+128)>>8
dst[i+w*j2] = pel if pel > 0 else 0
dst[i+w*j2] = pel if pel < 255 else 255
pel = (3*src[i+w*jp3]
-16*src[i+w*jp2]
+67*src[i+w*jp1]
+227*src[i+w*j]
-32*src[i+w*jm1]
+7*src[i+w*jm2]+128)>>8
dst[i+w*(j2+1)] = pel if pel > 0 else 0
dst[i+w*(j2+1)] = pel if pel < 255 else 255
return dst
Exécutez cette opération deux fois pour obtenir 4: 4: 4. Ensuite, il suffit de supprimer les lignes et les colonnes. Vous pouvez également quadrupler les chroma-pixels pour passer de 4: 2: 0 à 4: 4: 4, supprimer les lignes et les colonnes, puis calculer 4 valeurs Cb/Cr en 1 pour revenir à 4: 2: 0 encore une fois, tout dépend de la rigueur dont vous avez besoin :-)
Vous n'avez pas besoin d'aller à 4: 4: 4 et de revenir à 4: 2: 0. Cette dernière étape ré-échantillonnera l'image et diminuera encore la qualité. Il suffit de diviser les couleurs: http://stackoverflow.com/questions/17187193/resize-downsize-yuv420sp-image/30659193#30659193 –