CUDA实现Sobel滤波器出现间隔96px重复边缘问题求助
以下是针对你遇到的每隔96px出现重复边缘问题的具体排查方向:
验证线程坐标映射逻辑
核对核函数中threadIdx、blockIdx到输出像素(row, col)的计算是否准确,尤其是当图像宽度不是线程块宽度整数倍时,多余线程的掩码处理是否到位。96的间隔大概率和线程块维度(比如32x3的块,32*3=96)相关,可能是某维度的步长计算错误,导致线程重复读取了前一块的边缘数据。
可以在核函数中加入断言代码:assert(col < output_width && row < output_height),强制检查线程处理的坐标是否在合法范围内,快速定位越界访问。排查全局内存访问与Halo计算错误
检查带halo的输入图像宽度计算:原图像宽度为W时,x方向Sobel需要左右各1个像素的halo,因此输入宽度应为W+2。如果代码中错误使用了原图像宽度W作为输入宽度,会导致线程访问边缘时读取到相邻内存块的数据,进而出现重复图案。
同时确认内存读取的索引公式input[row * input_width + col]中的input_width是带halo后的正确值,而非原图像宽度。检查Halo填充的正确性
验证halo区域的填充逻辑:左边缘halo应填充原图像第0列的像素,右边缘halo应填充原图像最后一列的像素。如果填充了未初始化的内存或错误值,或者核函数中访问halo时的坐标偏移错误(比如偏移量应为1却写成了其他值),会导致边缘计算异常。
可以单独提取输出图像中重复位置的像素值,对比原图像对应区域的计算结果,确认是否和前一块的边缘值完全一致。核对线程块与网格维度配置
检查线程块的维度设置(比如dim3 block(32,3))和网格维度的计算(比如dim3 grid((W + block.x -1)/block.x, (H + block.y -1)/block.y))。如果网格宽度计算错误导致线程块重复覆盖同一区域,或者边缘线程块的多余线程未被掩码,也会引发重复问题。添加调试输出定位问题
在核函数中,针对出现重复的列(如96、192等),输出当前线程的row、col、读取的输入像素值以及计算后的输出值,对比正常位置的输出数据,看是否读取了错误的输入内存区域。也可以将带halo的输入图像保存为文件,直观检查边缘填充是否正确。
内容的提问来源于stack exchange,提问作者Harish Sathishchandra

