1. 目标:使用openmp实现图像滤波算法

给定一个输入图像,你的任务是将其划分为多个块,并使用多个进程对每个块进行滤波操作。
要求:
1、使用分段并行结构和指令section来并行执行不同的计算步骤。
2、使用单线程指令single或master确保某些代码段只在单个线程中执行。
3、使用线程同步和阻塞机制来确保所有线程在进入下一步处理之前完成当前步骤的计算。
4、使用任务池并行化来处理滤波操作,并根据图像块的大小和数量选择静态任务或动态任务。

2. 思路

思路:

(1). 根据结果目标元素位置,判断出要计算的原始图像数据和卷积核的位置边界

(2). 输出图像每个元素的计算当做一个任务

(3). 如果对数据分块的处理:

(a) 每个分块需要根据卷积核大小增加冗余数据空间,决定不采用分块模式。
(b) 遍历分块分配任务仍需要放在single单线程内处理
(c) 分块处理增加了代码复杂性,并无其他优点。决定不采用分快处理

3. 代码

#include <stdio.h>
#include <stdlib.h>
#include <omp.h> #define N 5 //输入图像方阵列维度
#define FN 3 //卷积核方阵列维度 void print_matrixS(unsigned char* matrix, int rows, int cols)
{
printf("matrix:\n");
for (size_t i = 0; i < rows; i++)
{
for (size_t j = 0; j < cols; j++)
printf("%d\t",matrix[i*cols+j]);
printf("\n");
}
} void main()
{
unsigned char inPic[N][N] = {0}; //输入图像
unsigned char outPic[N][N] = {0}; //输出图像
unsigned char conv[FN][FN] = {0}; //卷积核
double startTime,endTime; //计算的起始终止时间
//输入图像初始化
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
inPic[i][j] = rand()%256;
}
//初始化卷积核,中值滤波初始化为1
for(int i=0;i<FN;i++)
{
for(int j=0;j<FN;j++)
conv[i][j] = 1;
}
omp_set_num_threads(10);
startTime = omp_get_wtime();
//计算
#pragma omp parallel proc_bind(close)
{
//在单线程内分配任务
#pragma omp single
{
// #pragma omp for collapse(2) schedule(guided)
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
//将每个输出图像数据的计算都作为一个task
#pragma omp task shared(conv)
{
//确定计算结果每个元素卷积要参与的输入图像的数据位置边界
int up,down,left,right;
int half = FN/2; //卷积核一半向下取整
left = (j - half)>=0 ? j-half : 0;
right = (j+half)<=N-1 ? j+half : N-1;
up = (i - half)>=0 ? i-half : 0;
down = (i+half)<=N-1 ? i+half : N-1;
int rNums,cNums; //参与计算的行列数
rNums = down - up +1;
cNums = right - left +1;
//需要确定卷积核参与计算的边界,只需要左上角坐标
int rBegin,cBegin;
rBegin = FN/2-(i-up);
cBegin = FN/2-(j-left);
// 计算: 均值滤波,采用先求和再平均,减少乘法次数和误差
int sum=0;
int weightSum = 0;
for(int r=up;r<=down;r++,rBegin++)
{
for(int c=left,cTempBegin=cBegin;c<=right;c++,cTempBegin++)
{
sum += inPic[r][c] * conv[rBegin][cTempBegin];
weightSum += conv[rBegin][cTempBegin];
}
}
double e = 1.0/(double)weightSum;
outPic[i][j] = (short)(sum*e);
}
}
}
}
}
#pragma omp taskwait
endTime = omp_get_wtime();
printf("inPicSize %d useSec %f\n",N,(double)(endTime-startTime));
print_matrixS((unsigned char*)inPic,N,N);
print_matrixS((unsigned char*)outPic,N,N);
// print_matrixF((float*)conv,FN,FN);
}

高性能计算-openmp-图像卷积滤波算法(12)的更多相关文章

  1. Win8 Metro(C#)数字图像处理--2.51图像统计滤波算法

    原文:Win8 Metro(C#)数字图像处理--2.51图像统计滤波算法  [函数名称]   图像统计滤波   WriteableBitmap StatisticalFilter(Writeab ...

  2. Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法

    原文:Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法  [函数名称]   高斯平滑滤波器      GaussFilter(WriteableBitmap src,int r ...

  3. 基于FPGA的均值滤波算法实现

    我们为了实现动态图像的滤波算法,用串口发送图像数据到FPGA开发板,经FPGA进行图像处理算法后,动态显示到VGA显示屏上,前面我们把硬件平台已经搭建完成了,后面我们将利用这个硬件基础平台上来实现基于 ...

  4. zz图像卷积与滤波的一些知识点

    Xinwei: 写的通俗易懂,终于让我这个不搞CV.不搞图像的外行理解卷积和滤波了. 图像卷积与滤波的一些知识点 zouxy09@qq.com http://blog.csdn.net/zouxy09 ...

  5. 用python实现对图像的卷积(滤波)

    之前在看卷积神经网络,很好奇卷积到底是什么,最后看到了这篇文章http://blog.csdn.net/zouxy09/article/details/49080029,讲得很清楚,这篇文章中提到了对 ...

  6. 基于Vivado HLS在zedboard中的Sobel滤波算法实现

     基于Vivado HLS在zedboard中的Sobel滤波算法实现 平台:zedboard  + Webcam 工具:g++4.6  + VIVADO HLS  + XILINX EDK + ...

  7. Python下opencv使用笔记(图像频域滤波与傅里叶变换)

    Python下opencv使用笔记(图像频域滤波与傅里叶变换) 转载一只程序喵 最后发布于2018-04-06 19:07:26 阅读数 1654  收藏 展开 本文转载自  https://blog ...

  8. 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果(速度可实时)

    最新的效果见 :http://video.sina.com.cn/v/b/124538950-1254492273.html 可处理视频的示例:视频去雾效果 在图像去雾这个领域,几乎没有人不知道< ...

  9. paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他

    在图像去雾这个领域,几乎没有人不知道<Single Image Haze Removal Using Dark Channel Prior>这篇文章,该文是2009年CVPR最佳论文.作者 ...

  10. OPENCV基本滤波算法

    图像滤波的主要目的是为了在保留图像细节的情况下尽量的对图像的噪声进行消除,从而是后来的图像处理变得更加的方便. 图像的滤波效果要满足两个条件:1.不能损坏图像的轮廓和边缘这些重要的特征信息.2.图像的 ...

随机推荐

  1. 查看 Homebrew 管理的服务的日志

    TL;DR 首先找到 log 文件的位置: 对于 macOS (arm64),log 文件在 /opt/homebrew/var/log 目录下 对于 macOS (x86_64),log 文件在 / ...

  2. docker高级篇-docker-compose容器编排介绍及实战

    Docker-compose是什么?能干嘛?解决了哪些痛点? 是什么? Docker-compose是Docker官方推出 的一个工具软件,可以管理多个Docker容器组成的一个应用.你需要编写一个一 ...

  3. iptables 命令使用帮助总结

    本文为博主原创,转载请注明出处: 1.iptables 命令帮助参数 root@controller1:~# iptables --help iptables v1.6.1 Usage: iptabl ...

  4. Maven 依赖项管理&&依赖范围

    依赖管理   使用坐标导入jar包     1.在pom.xml 中编写 <dependencies> 标签     2.在 <dependencies> 标签中使用 < ...

  5. QT硬件通讯基础

    QT硬件通讯基础 使用AI技术辅助生成 1 QT与硬件通讯概述 1.1 QT硬件通讯的基本概念 1.1.1 QT硬件通讯的基本概念 QT硬件通讯的基本概念 QT硬件通讯的基本概念 QT作为一种跨平台的 ...

  6. IDEA如何查看每一行代码的提交记录(人员,时间)

    前言 我们在使用IDEA开发时,一般需要使用git来管理我们的代码,而且大家协同开发.   有时候,我们在开发的时候,经常需要看一下当前的代码时谁开发的,除了看类上面的作者外,更精细的方式是看每一行代 ...

  7. [29] CSP模拟2

    A.不相邻集合 考虑值域上连续的段,可以发现连续的长度为 \(x\) 的段的贡献必定为 \(\lceil{\frac{x}{2}}\rceil\) 考虑并查集维护值域连续的段的大小,每次询问求出全部连 ...

  8. KASAN 中kasan_multi_shot 的作用

    kasan_multi_shot 是 Linux 内核配置选项之一,与 Kernel Address Sanitizer (KASAN) 相关.KASAN 是一种内核内存错误检测工具,能够检测内核代码 ...

  9. USB2.0 USB3.0 供电情况及规定

    USB(通用串行总线)的不同版本在供电能力和规定上有所不同.以下是关于USB 2.0.USB 3.0和USB 3.1供电情况的详细信息: USB 2.0 最大供电电流: 500毫安 (mA) 最大供电 ...

  10. vue前端开发仿钉图系列(7)底部数据列表的开发详解

    底部数据列表主要是记录图层下面对应的点线面数据,点击单元行或者查看或者编辑,弹出右侧编辑页面,点击单元行地图定位到相应的绘图位置.里面的难点1是动态绑定字段管理编辑的字段以及对应的value值,2是点 ...