在《Haar小波变换的快速实现》一文里我们提到了Haar小波变换的计算,在这里我们使用CUDA实现文中提到的计算方式。
02 | _cuda_haar( float *A, float *B, int w, int h, int b_w, int b_h, int row_scan) |
04 | int i = blockIdx.x * blockDim.x + threadIdx.x; |
05 | int j = blockIdx.y * blockDim.y + threadIdx.y; |
07 | int extern_w = b_w * 2; |
08 | int extern_h = b_h * 2; |
22 | B[i * extern_w + b_w + j/2] = A[(i * w + j - 1) * 3 + 2] * 255; |
25 | B[i * extern_w + b_w + j/2] = (A[(i * w + j - 1) * 3 + 2] - A[(i * w + j) * 3 + 2]) * 255 * 0.5; |
32 | B[i * extern_w + j/2] = A[(i * w + j) * 3 + 2] * 255; |
35 | B[i * extern_w + j/2] = (A[(i * w + j) * 3 + 2] + A[(i * w + j + 1) * 3 + 2]) * 255 * 0.5; |
44 | B[(i/2 + b_h) * extern_w + j] = A[(i - 1) * extern_w + j]; |
47 | B[(i/2 + b_h) * extern_w + j] = (A[(i - 1) * extern_w + j] - A[i * extern_w + j]) * 0.5; |
53 | B[i/2 * extern_w + j] = A[i * extern_w + j]; |
56 | B[i/2 * extern_w + j] = (A[i * extern_w + j] + A[(i + 1) * extern_w + j]) * 0.5; |
代码有点乱,本来行变换和列变换是一次完成的,中间使用一个临时全局存储空间进行存储,但发现做列变换时从全局存储空间提出的数据有一部分是“脏”的,使用_threadfence做了同步处理。问题暂时没有找到,就使用这个替代方法了:先做行变换,然后将数据拷回内存,再拷回显存,第二次调用此内核函数,做列变换。
变换结果如下: