Per*_*abs 9 yuv image-resizing
我正在尝试调整(缩小)YUV420sp格式的图像.是否可以在不将其转换为RGB的情况下进行此类图像调整,从而直接操作YUV420sp像素阵列?我在哪里可以找到这样的算法?
谢谢
Fre*_*ihl 16
YUV 4:2:0平面看起来像这样:
----------------------
| Y | Cb|Cr |
----------------------
Run Code Online (Sandbox Code Playgroud)
哪里:
Y = width x height pixels
Cb = Y / 4 pixels
Cr = Y / 4 pixels
Total num pixels (bytes) = width * height * 3 / 2
Run Code Online (Sandbox Code Playgroud)
并且使用的子代数如下:

这意味着每个色度像素值在4个亮度像素之间共享.
一种方法是去除像素,确保保持/重新计算相应的Y-Cb-Cr关系.
接近最近邻插值但反转的东西.
另一种方法是首先将4:2:0子采样转换为4:4:4

在这里,您可以在亮度和色度数据之间进行1到1的映射.
这是在4:2:0和4:2:2之间插入色度的正确方法(亮度已经是正确的分辨率)python中的代码,按照h-link for c-dito.代码不是非常pythonic,只是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
Run Code Online (Sandbox Code Playgroud)
运行两次得到4:4:4.然后,只需删除行和列即可.
或者你可以将色度像素的四倍从4:2:0变为4:4:4,删除行和列然后将4 Cb/Cr值平均为1以再次回到4:2:0,它一切都取决于你需要多严格:-)
小智 7
这是一个Java函数,我用它来缩小YUV 420(或NV21)两倍.
该函数将图像放在一个字节数组中,同时将原始图像的宽度和高度作为输入,并返回一个字节数组中的图像,该数组的宽度和高度均等于原始宽度和高度的一半.
作为我的代码的基础,我使用了这个:在Android上旋转YUV字节数组
public static byte[] halveYUV420(byte[] data, int imageWidth, int imageHeight) {
byte[] yuv = new byte[imageWidth/2 * imageHeight/2 * 3 / 2];
// halve yuma
int i = 0;
for (int y = 0; y < imageHeight; y+=2) {
for (int x = 0; x < imageWidth; x+=2) {
yuv[i] = data[y * imageWidth + x];
i++;
}
}
// halve U and V color components
for (int y = 0; y < imageHeight / 2; y+=2) {
for (int x = 0; x < imageWidth; x += 4) {
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
i++;
yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x + 1)];
i++;
}
}
return yuv;
}
Run Code Online (Sandbox Code Playgroud)