在做 图像 处理的 程序 ,就是三维 图像滤波 来 去噪声的 问题 。
是 局部 滤波 , 也就是 新图像的 每一个 点的 值, 是 原始图像对应点 周围 一定 范围内的 点的 线性 叠加 。
譬如 256 X 256 X 256 的 图像 第 (128, 128, 128)点的 值 由 原始图像的 (108:148, 108:148, 108:148)的小块区域 决定 。
C程序 大致 如下
for(k=0; k<256; k++){
for(j=0; j<256; j++){
for(i=0;i<256;i++){
NewImage(k256256+j256+i) = 0.0
for(k1 = k - 20; k1 < k + 20, k1++){
for(j1 = j - 20; j1 < j + 20; j1++){
for(i1 = i - 20; i1 < i + 20; i1++){
NewImage(k256256+j256+i) += OldImage(k1256256 + j1 * 256 + i ) * coeff(k12020 + j1 * 20 + i1);
}
}
}
}
}
}
内循环边界做了限制 , 不是 k-20 和k+20那么 直接 ,这里 为了 书写 方便 就 这样 用了 。
这样的 程序 怎么 优化 ?
我只是 很初级的 入门者 ,
就把 最外面 两重 循环改 并行, 改成 cuda程序 , 就得到
global void Matfilter(float* OldImage, float* NewImage , float* coeff){
int k = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
for(i=0;i<256;i++){
NewImage(k256256+j256+i) = 0.0
for(k1 = k - 20; k1 < k + 20, k1++){
for(j1 = j - 20; j1 < j + 20; j1++){
for(i1 = i - 20; i1 < i + 20; i1++){
NewImage(k256256+j256+i) += OldImage(k1256256 + j1 * 256 + i ) * coeff(k12020 + j1 * 20 + i1);
}
}
}
}
}
coeff是 已知 的 系数矩阵。
这样 在 tesla c1060上 只有6倍 的 速度 。
很不 优化。
但由于 每个线程 都要 读取 很大范围的数据 (OldImage), 我也不知道 该 则样 用 共享存储器 ( shared memory).
请 大侠赐教 怎样改上面的 程序和优化 它, 非常感激 。