高性能计算-openmp-图像卷积滤波算法(12)
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)的更多相关文章
- Win8 Metro(C#)数字图像处理--2.51图像统计滤波算法
原文:Win8 Metro(C#)数字图像处理--2.51图像统计滤波算法 [函数名称] 图像统计滤波 WriteableBitmap StatisticalFilter(Writeab ...
- Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法
原文:Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法 [函数名称] 高斯平滑滤波器 GaussFilter(WriteableBitmap src,int r ...
- 基于FPGA的均值滤波算法实现
我们为了实现动态图像的滤波算法,用串口发送图像数据到FPGA开发板,经FPGA进行图像处理算法后,动态显示到VGA显示屏上,前面我们把硬件平台已经搭建完成了,后面我们将利用这个硬件基础平台上来实现基于 ...
- zz图像卷积与滤波的一些知识点
Xinwei: 写的通俗易懂,终于让我这个不搞CV.不搞图像的外行理解卷积和滤波了. 图像卷积与滤波的一些知识点 zouxy09@qq.com http://blog.csdn.net/zouxy09 ...
- 用python实现对图像的卷积(滤波)
之前在看卷积神经网络,很好奇卷积到底是什么,最后看到了这篇文章http://blog.csdn.net/zouxy09/article/details/49080029,讲得很清楚,这篇文章中提到了对 ...
- 基于Vivado HLS在zedboard中的Sobel滤波算法实现
基于Vivado HLS在zedboard中的Sobel滤波算法实现 平台:zedboard + Webcam 工具:g++4.6 + VIVADO HLS + XILINX EDK + ...
- Python下opencv使用笔记(图像频域滤波与傅里叶变换)
Python下opencv使用笔记(图像频域滤波与傅里叶变换) 转载一只程序喵 最后发布于2018-04-06 19:07:26 阅读数 1654 收藏 展开 本文转载自 https://blog ...
- 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果(速度可实时)
最新的效果见 :http://video.sina.com.cn/v/b/124538950-1254492273.html 可处理视频的示例:视频去雾效果 在图像去雾这个领域,几乎没有人不知道< ...
- paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他
在图像去雾这个领域,几乎没有人不知道<Single Image Haze Removal Using Dark Channel Prior>这篇文章,该文是2009年CVPR最佳论文.作者 ...
- OPENCV基本滤波算法
图像滤波的主要目的是为了在保留图像细节的情况下尽量的对图像的噪声进行消除,从而是后来的图像处理变得更加的方便. 图像的滤波效果要满足两个条件:1.不能损坏图像的轮廓和边缘这些重要的特征信息.2.图像的 ...
随机推荐
- [WPF]数据绑定时为何会出现StringFormat失效
在数据绑定过程中,我们经常会使用StringFormat对要显示的数据进行格式化,以便获得更为直观的展示效果,但在某些情况下格式化操作并未生效,例如 Button的 Content属性以及ToolTi ...
- docker高级篇-docker-compose容器编排介绍及实战
Docker-compose是什么?能干嘛?解决了哪些痛点? 是什么? Docker-compose是Docker官方推出 的一个工具软件,可以管理多个Docker容器组成的一个应用.你需要编写一个一 ...
- PyTorch从入门到放弃之张量模块
目录 张量的数据类型 torch.rand()函数 torch.randn()函数 torch.normal()函数 torch.linspace()函数 torch.manual_seed()函数 ...
- C#/.NET/.NET Core优质学习资料,干货收藏!
前言 今天大姚给大家分享一些C#/.NET/.NET Core优质学习资料,希望可以帮助到有需要的小伙伴. 什么是 .NET? .NET 是一个免费的.跨平台的.开源开发人员平台,用于构建许多不同类型 ...
- 【Azure Developer】上手 The Best AI Code "Cursor" : 仅仅7次对话,制作个人页面原型,效果让人惊叹!
AI Code 时代早已开启,自己才行动.上手一试,让人惊叹.借助这感叹的情绪,把今天操作Cursor的步骤记录下来,也分享给大家. 推荐大家上手一试,让你改变! 准备阶段 下载 Cursor(htt ...
- linux修改limits.conf不生效
正常情况下, /etc/security/limits.conf 的改动,重新登录就可以生效, 我遇到的问题最后的解决方案是重启虚拟机解决了,也参考了很多网上的文章,整理记录一下 一.修改方法 1.临 ...
- 小程序bindinput和bindblur赋值延迟问题解决
小程序bindinput和bindblur赋值延迟问题解决 问题链接:https://developers.weixin.qq.com/community/develop/doc/000a0ebdc4 ...
- RS485与ModbusRTU
前言 大家好!我是付工. 每次听到别人说RS485通信协议,就很想去纠正他. 今天跟大家聊聊关于RS485的那些事. 接口标准 首先明确一点,RS485不是通信协议,而是一种接口标准,它还有2个兄弟: ...
- ServiceMesh 1:大火的云原生微服务网格,究竟好在哪里?
1 关于云原生 云原生计算基金会(Cloud Native Computing Foundation, CNCF)的官方描述是: 云原生是一类技术的统称,通过云原生技术,我们可以构建出更易于弹性扩展. ...
- Azure 入门系列 (第四篇 Key Vault)
本系列 这个系列会介绍从 0 到 1 搭建一个 Web Application 的 Server. 间中还会带上一些真实开发常用的功能. 一共 6 篇 1. Virtual Machine (VM) ...