TRT2-CUDA_Runtime_Api-3 加速Warpaffine

__device__ void affine_project(float* matrix, int x, int y, float* proj_x, float* proj_y){

    // matrix
    // m0, m1, m2
    // m3, m4, m5
    *proj_x = matrix[0] * x + matrix[1] * y + matrix[2];
    *proj_y = matrix[3] * x + matrix[4] * y + matrix[5];
}

__global__ void warp_affine_bilinear_kernel(
    uint8_t* src, int src_line_size, int src_width, int src_height, 
    uint8_t* dst, int dst_line_size, int dst_width, int dst_height, 
	uint8_t fill_value, AffineMatrix matrix
){
    /* 
    建议先阅读代码,若有疑问,可点击抖音短视频进行辅助讲解(建议1.5倍速观看)
        - https://v.douyin.com/Nhr4vTF/
     */
    
    int dx = blockDim.x * blockIdx.x + threadIdx.x; 
    int dy = blockDim.y * blockIdx.y + threadIdx.y;//每一个线程负责处理一个像素的三个通道。
    if (dx >= dst_width || dy >= dst_height)  return;

    float c0 = fill_value, c1 = fill_value, c2 = fill_value;
    float src_x = 0; float src_y = 0;
    affine_project(matrix.d2i, dx, dy, &src_x, &src_y);//已知dxdy的位置,src_x , src_y 去哪里取值. 因为这是一个平移变换的核函数,需要对于像素值进行拷贝

    
    /*
    建议先阅读代码,若有疑问,可点击抖音短视频进行辅助讲解(建议1.5倍速观看)
        - 双线性理论讲解:https://v.douyin.com/NhrH2tb/
        - 代码代码:https://v.douyin.com/NhrBqpc/ 
     */
    if(src_x < -1 || src_x >= src_width || src_y < -1 || src_y >= src_height){
        // out of range
        // src_x < -1时,其高位high_x < 0,超出范围
        // src_x >= -1时,其高位high_x >= 0,存在取值
    }else{
        int y_low = floorf(src_y);//向下取整
        int x_low = floorf(src_x);
        int y_high = y_low + 1;
        int x_high = x_low + 1;

        uint8_t const_values[] = {fill_value, fill_value, fill_value};//三通道给三个值,给那些不在区域之内的,不正常的值。
        float ly    = src_y - y_low;
        float lx    = src_x - x_low;            //求取每个小矩形的长宽
        float hy    = 1 - ly;
        float hx    = 1 - lx;
        float w1    = hy * hx, w2 = hy * lx, w3 = ly * hx, w4 = ly * lx;        //求取每个小矩形的面积
        uint8_t* v1 = const_values;
        uint8_t* v2 = const_values;
        uint8_t* v3 = const_values;
        uint8_t* v4 = const_values;
        if(y_low >= 0){
            if (x_low >= 0)
                v1 = src + y_low * src_line_size + x_low * 3; //拿到正常值的首地址 (比如4*3的矩阵的(1,1)那就是第一行的srcline(4*1 *3(channel) +1*3)拿到了这个1的地址,之后就可以取rgb三个通道的值)

            if (x_high < src_width)
                v2 = src + y_low * src_line_size + x_high * 3;
        }
        
        if(y_high < src_height){
            if (x_low >= 0)
                v3 = src + y_high * src_line_size + x_low * 3;

            if (x_high < src_width)
                v4 = src + y_high * src_line_size + x_high * 3;
        }
        
        c0 = floorf(w1 * v1[0] + w2 * v2[0] + w3 * v3[0] + w4 * v4[0] + 0.5f); //0.5f是为了四舍五入
        c1 = floorf(w1 * v1[1] + w2 * v2[1] + w3 * v3[1] + w4 * v4[1] + 0.5f);
        c2 = floorf(w1 * v1[2] + w2 * v2[2] + w3 * v3[2] + w4 * v4[2] + 0.5f);
    }

    uint8_t* pdst = dst + dy * dst_line_size + dx * 3;
    pdst[0] = c0; pdst[1] = c1; pdst[2] = c2;
}

warpaffine最核心的kernel就是这一段了。

  • 分配线程,确保一个线程负责处理一个像素的三个通道。

  • 对于尺度映射的浮点坐标,分别取其左右临点,分别为v1,v2,v3,v4。
  • 运用临点坐标求面积,求出权重。
  • 运用权重及各临点的RGB 值,求该映射浮点的RGB 值,最终即为dst的RGB 值

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值