一 selfguided_restoration_fast_internal 函数作用
selfguided_restoration_fast_internal是SVT-AV1 编码器中用于自引导恢复Guided Resration SGR 的一个内部函数,通过自引导滤波技术对输入的去燥他图像数据进行处理,生成一个去燥版本的图像,以下是该函数的详细解释。
参数说明:
dgd 指向输入的去燥图像数据的指针,表示需要恢复的图像
width 输入图像的宽度
height 输入图像的高度
dgd_stride 输入图像的步长,即每行像素的字节数
dst 指向输出的恢复图像数据的指针,用于存储处理后的图像
dst_stride 输出图像步长,即每行恢复图像数据的字节数
bit_depth 图像位深,表示每个像素的位数
sgr_params_idx 自引导恢复参数的索引,用于选择特定的恢复参数
redius_idx 半径参数的索引,用于选择特定的半径值
说明:
1 获取自引导恢复参数
根据sgr_params_idx和radius_idx 从预定义的参数表中获取自引导恢复参数,包括半径r和噪声参数e
2 去燥处理
使用自引导滤波技术对输入的去燥图像数据dgd进行处理,生成一个去燥版本的图像
2 这个去燥版本的图像是通过自引导滤波器生成的,保留了边缘信息,同时减少了噪声
3 输出结果
将处理后的去燥图像数据存储到dst中
作用
去燥 该函数的主要作用是通过自引导滤波技术对输入图像进行去燥处理,生成一个去燥版本的图像
参数控制 通过sgr_params_idx个radius_idx参数,可以灵活的选择不同的去燥强度和方式,以适应不同图像的处理需求
总结:
selfguided_resration_fast_internal 是SVT-AV1编码器中用于自引导恢复的一个关键组件,通过自引导滤波技术对输入的去燥图像数据进行处理,生成一个去燥版本的图像,用于进一步的图像恢复和优化,该函数的参数设计使其能够灵活的适应不同的图像处理需求。
二 函数注释
static void selfguided_restoration_fast_internal(int32_t *dgd, int32_t width, int32_t height, int32_t dgd_stride,
int32_t *dst, int32_t dst_stride, int32_t bit_depth,
int32_t sgr_params_idx, int32_t radius_idx)
{
//获取自引导恢复参数,根据参数索引sgr_params_idx 从预定义的参数表中获取
const SgrParamsType *const params = &svt_aom_eb_sgr_params[sgr_params_idx];
//获取半径参数,根据radius_idx选择特定的半径值
const int32_t r = param->r[radius_idx];
//计算扩展后的图像宽度,包括水平方向的边界扩展
const int32_t width_ext = width _ 2 * SGRPROJ_BORDER_HORZ;
//计算扩展后的图像高度,包括垂直方向的边界扩展
const int32_t height_ext = height + 2 * SGRPROJ_BORDER_VERT;
//调整缓冲区步长,避免缓存效果不佳,同时与SIMD版本保持一致
int32_t buf_stride = (width_ext + 3) & ~3 + 16;
//定义局部数组,用于存储中间计算结果A和B
int32_t a_[RESRATION_PROC_UNIT_PELS];
int32_t b_[RESRATION_PROC_UNIT_PELS];
//指向中间计算结果A和B的指针
int32_t *A = a_;
int32_t *B = b_;
//循环变量
//计算B数组,使用boxsum 函数对输入图像进行处理
boxsum(dgd - dgd_stride * SGRPROJ_BORDER_VERT - SGRPROJ_BORDER_HORZ, width_ext, height_ext, dgd_stride, r, 0, 0, B, buf_stride);
//计算A数组,使用boxsum函数对输入图像进行处理
boxsum(dgd - dgd_stride * SGRPROJ_BORDER_VERT - SGRPROJ_BORDER_HORZ, widht_ext, height_ext, dgd_stride, r, 1, A, buf_stride);
//调整A和B数组的起始位置,跳过边界扩展部分
A += SGRPROJ_BORDER_VERT * buf_stride + SGRPROJ_BORDER_BORZ;
B += SGRPROJ_BORDER_VERT * buf_stride + SGRPROJ_BORDER_HORZ;
//计算A和B数组的最终值,包括边界扩展部分
for (int i = -1; i < height + 1; i += 2) {
for (int j = -1; j < width + 1; ++j) {
const int32_t k = i * buf_stride + j;
const int32_t n = (2 r + 1) (2 r + 1);
//计算a值,进行位移操作以适应不同的位深
uint32_t a = ROUND_POWER_OF_TWO(A[k], 2 * (bit_depth - 8));
//计算b值,进行位移操作以适应不同的位深
uint32_t b = ROUND_POWER_OF_TWO(B[k], bit_depth - 8);
//根据Popoviciu 不等式计算p值,确保p非负
uint32_t p = (a n < b b)?0:a n - b * b;
//获取参数s,用于后续计算
const uint32_t s = params->s[radius_idx];
//计算z值,用于确定A[k]的值
const uint32_t z = ROUND_POWER_OF_TWO(p * s, SGRPROJ_MTABLE_BITS);
//计算A[k]的值,确保其在有效范围内
A[K] = SVT_AOM_EB_X_BY_XPLUS1[AOMIN(Z, 255)];
//计算B[k]的值,结合A[k]和B[k] 的中间结果
B[k] = (int32_t)ROUND_POWER_OF_TWO
B[k] = (int32_t)ROUND_POWER_OF_TWO(
(uint32_t)(SGRPROJ_SGR - A[k]) * (uint32_t)B[k] * (uint32_t)svt_aom_eb_one_by_x[n - 1],
SGRPROJ_RECIP_BITS);
}
//使用A和B数组计算最终的去燥图像
for (i = 0; i < height; ++i) {
if (!(i & 1)) { // even row 如果是偶数行
for (j = 0; j < width; ++j) {
const int32_t k = i * buf_stride + j;
const int32_t l = i * dgd_stride + j;
const int32_t m = i * dst_stride + j;
const int32_t nb = 5;
//计算a值,结合上下文的A值
const int32_t a = (A[k - buf_stride] + A[k + buf_stride]) * 6 +
(A[k - 1 - buf_stride] + A[k - 1 + buf_stride] + A[k + 1 - buf_stride] + A[k + 1 + buf_stride]) * 5;
//计算b值,结合上下文的B值
const int32_t b = (B[k - buf_stride] + B[k + buf_stride]) * 6 +
(B[k - 1 - buf_stride] + B[k - 1 + buf_stride] + B[k + 1 - buf_stride] + B[k + 1 + buf_stride]) * 5;
//计算最终的去燥像素值
const int32_t v = a * dgd[l] + b;
//将结果存储到输出数组dst中
dst[m] = ROUND_POWER_OF_TWO(v, SGRPROJ_SGR_BITS + nb - SGRPROJ_RST_BITS);
}
} else { // odd row //如果是奇数行
for (j = 0; j < width; ++j) {
const int32_t k = i * buf_stride + j;
const int32_t l = i * dgd_stride + j;
const int32_t m = i * dst_stride + j;
const int32_t nb = 4;
//计算a值,结合左右的A值
const int32_t a = A[k] * 6 + (A[k - 1] + A[k + 1]) * 5;
//计算b值,结合左右的B值
const int32_t b = B[k] * 6 + (B[k - 1] + B[k + 1]) * 5;
//计算最终的去燥像素值
const int32_t v = a * dgd[l] + b;
//将结果存储到输出数组dst中
dst[m] = ROUND_POWER_OF_TWO(v, SGRPROJ_SGR_BITS + nb - SGRPROJ_RST_BITS);
}
}
}
}
}
注释说明:
参数获取:从预定义的参数表中自引导恢复参数,包括半径和噪声参数
边界扩展:计算扩展的图像尺寸,包括水平和垂直方向的边界扩展
中间计算:使用boxsum函数计算中间数组A和B,这些数组用于后续的去燥处理
数学计算:通过数学公式计算最终的去燥像素值,结合中间数组A和B的结果
输出结果:将去燥后的像素值存储到输出数组dst中。