OpenCV中OpenMP的使用

vs2010中调用openMP,并添加头文件#include<omp.h>

代码来源:

作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/

#include "stdafx.h"

#include "cv.h" 
#include "highgui.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <omp.h>

#pragma comment(lib,"opencv_core2410d.lib")              
#pragma comment(lib,"opencv_highgui2410d.lib")              
#pragma comment(lib,"opencv_imgproc2410d.lib")    

 

void EdgeOpenMP(IplImage *src,IplImage *dst,int thresh) 
{ 
    int height    = src->height; 
    int width     = src->width; 
    int step      = src->widthStep; 
    uchar *data1      = (uchar *)src->imageData; 
    uchar *data2      = (uchar *)dst->imageData;

    int i=step; 
    #pragma omp parallel for 
    for(i=step+1;i<height*width;i++){ 
         if(abs(data1[i]-data1[i-1])>thresh || abs(data1[i]-data1[i-step])>thresh) 
            data2[i]=255;/* 对于单通道,前后两帧差分大于门限 
            或者对于多通道前后两帧的一个指标差分大于门限,则视为边缘*/ 
         else 
            data2[i]=0; 
    } 
}

void Edge(IplImage *src,IplImage *dst,int thresh) 
{ 
    int height    = src->height; 
    int width     = src->width; 
    int step      = src->widthStep; 
    uchar *data1      = (uchar *)src->imageData; 
    uchar *data2      = (uchar *)dst->imageData;

   int i=step; 
    for(i=step+1;i<height*width;i++){ 
         if(abs(data1[i]-data1[i-1])>thresh || abs(data1[i]-data1[i-step])>thresh) 
            data2[i]=255; 
         else 
            data2[i]=0; 
    } 
}


int main() 
{ 
  char filename[512]; 
  IplImage *src,*edge1,*edge2; 
  puts("File name:"); 
  gets(filename); 
  src = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE ); 
  edge1=cvCloneImage(src); 
  edge2=cvCloneImage(src);

  cvNamedWindow("src", CV_WINDOW_AUTOSIZE); 
  cvMoveWindow("src", 100, 100); 
  cvShowImage( "src", src); 
  cvNamedWindow("Edge", CV_WINDOW_AUTOSIZE); 
  cvMoveWindow("Edge", 200, 100); 
  cvNamedWindow("EdgeOpenMP", CV_WINDOW_AUTOSIZE); 
  cvMoveWindow("EdgeOpenMP", 300, 100); 
  /* 以上都是准备一些窗口和图形基本数据 */

  int tekrar=100;//运行次数 
  int thresh=30; 
  double start, end,t1, t2; 
  
  /* 计算没有使用OpenMP优化的时间 */ 
  start= (double)cvGetTickCount();//记下开始的时钟计数,以便计算函数或用户代码执行时间 
  for(int i=0;i<tekrar;i++) 
    Edge(src,edge1,thresh); 
  end= (double)cvGetTickCount();//记下结束的时钟计数 
  t1= (end-start)/((double)cvGetTickFrequency()*1000.);//计算运行时间,以毫秒为单位 
  printf( "Run time without OpenMP = %g ms\n", t1 );

  /* 计算使用了OpenMP优化的时间 */ 
  start= (double)cvGetTickCount(); 
  for(int i=0;i<tekrar;i++) 
    EdgeOpenMP(src,edge2,thresh); 
  end= (double)cvGetTickCount(); 
  t2= (end-start)/((double)cvGetTickFrequency()*1000.); 
  printf( "Run time with OpenMP = %g ms\n", t2 );

  printf( "Performance ratio (%%) = %% %.1f \n", 100*(t1/t2-1) );

  cvShowImage( "Edge", edge1); 
  cvShowImage( "EdgeOpenMP", edge2); 
  cvWaitKey(); 
  cvDestroyWindow("Edge"); 
  cvDestroyWindow("EdgeOpenMP"); 
  cvReleaseImage(&src); 
  cvReleaseImage(&edge1); 
  cvReleaseImage(&edge2); 
}
这是我的结果:


这里的测试结果:
http://blog.csdn.net/augusdi/article/details/8808226
  在cpp文件中添加如下代码:

[cpp] view plaincopyprint?

  1. #include "stdafx.h"  
  2. #include<omp.h>  
  3. #include<iostream>  
  4. usingnamespace std;  
  5. //循环测试函数  
  6. void test()  
  7. {  
  8. for(int i=0;i<10000;i++)  
  9. {  
  10. }  
  11. }  
  12. int _tmain(int argc,_TCHAR* argv[])  
  13. {  
  14. cout<<"这是一个串行测试程序!\n";  
  15. double start = omp_get_wtime( );//获取起始时间  
  16. for(int i = 0; i < 10000; i++)  
  17. {   
  18. test();  
  19. }  
  20. double end = omp_get_wtime( );  
  21. cout<<"计算耗时为:"<<end -start<<"\n";  
  22. cin>>end;  
  23. return 0;  
  24. }  
#include "stdafx.h"

#include<omp.h>

#include<iostream>

usingnamespace std;


//循环测试函数
void test()
{
for(int i=0;i<10000;i++)
{

}
}


int _tmain(int argc,_TCHAR* argv[])
{
cout<<"这是一个串行测试程序!\n";
double start = omp_get_wtime( );//获取起始时间

for(int i = 0; i < 10000; i++)
{ 
test();
}

double end = omp_get_wtime( );

cout<<"计算耗时为:"<<end -start<<"\n";

cin>>end;

return 0;
}

       以上代码中红色字体为添加的代码,以上程序是一个典型的串行程序,经过随机运行10次,其平均耗时约0.283273s(具体所耗时间跟测试计算机有密切的关系,测试电脑CPU采用Core I7 2630QM,4核)。

       下面将其转换成并行程序,只需要在for循环加上#pragma omp parallel for即可,如下代码(注意红色部分):

[cpp] view plaincopyprint?

  1. #include "stdafx.h"  
  2. #include<omp.h>  
  3. #include <iostream>  
  4. using namespace std;  
  5. //循环测试函数  
  6. void test()  
  7. {  
  8. for(inti=0;i<10000;i++)  
  9. {  
  10. }  
  11. }  
  12. int _tmain(int argc, _TCHAR* argv[])  
  13. {  
  14. cout<<"这是一个并行测试程序!\n";  
  15. doublestart = omp_get_wtime( );//获取起始时间  
  16. #pragma ompparallel for  
  17. for(inti = 0; i < 10000; i++)   
  18. {  
  19. test();  
  20. }  
  21. doubleend = omp_get_wtime( );  
  22. cout<<"计算耗时为:"<<end -start<<"\n";  
  23. cin>>end;  
  24. return0;  
  25. }  
#include "stdafx.h"

#include<omp.h>

#include <iostream>

using namespace std;


//循环测试函数
void test()
{
for(inti=0;i<10000;i++)
{

}
}

int _tmain(int argc, _TCHAR* argv[])
{
cout<<"这是一个并行测试程序!\n";

doublestart = omp_get_wtime( );//获取起始时间


#pragma ompparallel for
for(inti = 0; i < 10000; i++) 
{
test();
}


doubleend = omp_get_wtime( );

cout<<"计算耗时为:"<<end -start<<"\n";

cin>>end;

return0;
}

       同样,也经过10次随机的运行,其平均耗时约为0.06358044s,两种不同运行方式的比较结果如下表所示:

次数

串行

并行

1

0.283382

0.0746704

2

0.283654

0.0686404

3

0.283212

0.0536631

4

0.280234

0.0517737

5

0.283041

0.0717588

6

0.283126

0.0524264

7

0.281881

0.0580316

8

0.283301

0.0730386

9

0.284545

0.0745088

10

0.286353

0.0572926

平均值

0.283273

0.06358044

       两种运行方式的结果如下图所示:

       从上面的分析结果可见,采用OpenMP并行所耗时间仅为串行的22.44%,节约近4.5倍的时间。

相关程序源码下载地址: http://download.csdn.net/detail/xwebsite/3843187

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 基于重心偏移的视差计算

        视差的计算,主要要计算待匹配图像对应像素的水平偏移,那么针对一个物体而言,其在场景中的视差大体上应该是平滑的,所以可以直接针对分割出的物体计算重心的水平...

    流川疯
  • OpenCV计算物体的重心坐标(2值图像)

    http://download.csdn.net/detail/wangyaninglm/9389338 

    流川疯
  • leetcode 204题求素数个数

    Count the number of prime numbers less than a non-negative number, n

    流川疯
  • The Triangle

    从顶到底的最大和是多少 #include<stdio.h> #include<string.h> int main() { int n,i,j; ...

    用户1624346
  • NOIP 2017普及组复赛C/C++详细题解报告

    https://wenku.baidu.com/view/f3fe5a326ad97f192279168884868762cbaebb71.html?from=...

    海天一树
  • P2331 [SCOI2005]最大子矩阵

    题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。 输入输出格式 输入格式: 第一行...

    attack
  • 五分钟小知识:如何用算法高效寻找素数?

    不要觉得素数的定义简单,恐怕没多少人真的能把素数相关的算法写得高效。本文就主要聊这样一个函数:

    五分钟学算法
  • 如何用算法高效寻找素数?

    不要觉得素数的定义简单,恐怕没多少人真的能把素数相关的算法写得高效。本文就主要聊这样一个函数:

    乔戈里
  • 算法专题:如何用算法高效寻找素数?

    不要觉得素数的定义简单,恐怕没多少人真的能把素数相关的算法写得高效。本文就主要聊这样一个函数:

    帅地
  • HDU 5636 Shortest Path(Floyed,枚举)

    Shortest Path Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131...

    ShenduCC

扫码关注云+社区

领取腾讯云代金券