实现YUV I420格式的图像边界扩充

对I420格式的YUV图片实现填充padding效果


使用libyuv对I420的yuv图像进行处理的过程中,需要自己实现图像填充,通过在边界填充固定的颜色值形成一个正方形图像。类似于OpenCV中的copyMakeBorder函数,可以达到对图像扩充边界的效果。

  • I420的存储格式

属于YUV Planar格式的一种,先连续存储所有像素点的 Y 分量,紧接着存储所有像素点的 U 分量,再是 V 分量。相对于其它YUV存储格式是比较简单的,因为三个分量是按顺序连续存储的,所以libyuv对于图像数据的裁剪、缩放、旋转等操作很多都是基于I420格式的处理。

Y Y   Y Y 
Y Y   Y Y
U U 
V V 

对于一组I420数据,Y的size为width * height,U和V的size都是width * height * 1 / 4 ,总size为width * height * 3 / 2。所以U分量的起始位置是width * height ,V分量的起始位置是width * height * 5 / 4。

  • 如何实现边界填充?

对于一个320 * 240分辨率大小的图片,需要对底部80像素进行颜色填充,处理后的图片分辨率为320 * 320 。
我们这里填充YUV色值(0,128,128)即黑色。代码如下:

	先填充Y分量
	for (int i = 0; i < h; i++) {
       	for (int j = 0; j < w; j++) {
            if (i < topBorder || i >= bottomBorder || j < leftBorder || j >= rightBorder) {
                dst_i420_data[i * w + j] = Y; //给超出边界的Y分量赋值0
            } else {
                if (row < src_i420_y_size) {
                    //范围内的Y分量沿用原I420的Y分量
                    dst_i420_data[i * w + j] = src_i420_data[row++];
                }
            }
        }
	}
	//再分别填充U、V分量
    int row_u = src_i420_y_size; //U分量的起始位置
    int row_v = src_i420_y_size * 5 / 4; //V分量的起始位置
    int row_v_fixed = row_v;
    int ySize = w * h;
    int uSize = w * h * 5 / 4;
    int uvW = w >> 1; //U、V分量的宽
    int uvH = h >> 1; //U、V分量的高
    //避免在循环内重复计算
    leftBorder = leftBorder >> 1;
    rightBorder = rightBorder >> 1;
    topBorder = topBorder >> 1;
    bottomBorder = bottomBorder >> 1;
    for (int i = 0; i < uvH; i ++) {
        for (int j = 0 ; j < uvW; j ++) {
            if (j < leftBorder || j >= rightBorder || i < topBorder || i >= bottomBorder) {
                //给超出边界的U、V分量分别赋值128
                dst_i420_data[ySize + i * uvW + j] = U;
                dst_i420_data[uSize + i * uvW + j] = V;
            } else {
                if (row_u < row_v_fixed) {
                    //范围内的U、V分量沿用原I420的U、V分量
                    dst_i420_data[ySize + i * uvW + j] = src_i420_data[row_u++];
                    dst_i420_data[uSize + i * uvW + j] = src_i420_data[row_v++];
                }
            }
        }
    }
  • 测试效果
    内部测试速度还是蛮快的,能在1ms内处理完毕。
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_23069607/article/details/124494349
今日推荐