如何并行优化图像秩变换(Rank Transform)的嵌套for循环?
秩变换运算优化建议
以下是可以进一步降低运行耗时的优化方案:
1 消除冗余内存访问开销
- 替换
cv::Mat::at<>访问方式:at方法默认带边界检查逻辑,会带来额外性能损耗。改为直接通过行指针访问像素,外层v循环内预先获取当前中心行指针,内层窗口遍历也直接用行指针访问,减少边界检查开销。 - 预先缓存中心像素值:内层u循环开始时就将当前中心像素的灰度值存到局部变量,不需要在内层窗口遍历的每次比较中都重复从内存读取中心像素。
2 循环逻辑优化
- 滑动窗口降复杂度:当前每个像素都完整遍历整个窗口的计算逻辑时间复杂度为O(HWK²)(K为窗口边长),可以改为滑动窗口更新:横向滑动时,仅移除左移出列的所有像素比较结果、新增右移入列的所有像素比较结果,复杂度直接降到O(HWK),15x15窗口下计算量直接降低到原来的1/15。
- 开启向量化:给内层uWin遍历的循环添加
#pragma omp simd指令,让编译器自动生成SIMD指令并行处理一行窗口内的像素比较逻辑,MSVC下配合/O2优化选项生效。
3 OpenMP调度优化
- 给并行指令指定静态调度策略:修改为
#pragma omp parallel for schedule(static, 8) num_threads(8),你的i7-7700K为4核8线程,指定8线程、按8行块静态分配任务,可以减少多线程调度开销,提升缓存命中率。
4 算法级优化
- 改用直方图秩计算:8位灰度图的灰度范围只有0~255,滑动窗口时维护一个大小为256的灰度直方图,中心像素的秩就是直方图中小于中心灰度的像素总数。滑动窗口时只需要更新移出和移入像素的直方图计数,计算秩只需要累加直方图前N项,时间复杂度可以降到O(H*W),性能会有数量级的提升。
内容的提问来源于stack exchange,提问作者Miau
相关产品推荐
相关产品推荐

