zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", t2 );
    
      printf( "Performance ratio (%%) = %% %.1f 
    ", 100*(t1/t2-1) );
    
      cvShowImage( "Edge", edge1); 
      cvShowImage( "EdgeOpenMP", edge2); 
      cvWaitKey(); 
      cvDestroyWindow("Edge"); 
      cvDestroyWindow("EdgeOpenMP"); 
      cvReleaseImage(&src); 
      cvReleaseImage(&edge1); 
      cvReleaseImage(&edge2); 
    }
    
    这是我的结果:
    image
    
    这里的测试结果:
    http://blog.csdn.net/augusdi/article/details/8808226
      在cpp文件中添加如下代码:
    1. #include "stdafx.h"  
    2.   
    3. #include<omp.h>  
    4.   
    5. #include<iostream>  
    6.   
    7. usingnamespace std;  
    8.   
    9.   
    10. //循环测试函数  
    11. void test()  
    12. {  
    13. for(int i=0;i<10000;i++)  
    14. {  
    15.   
    16. }  
    17. }  
    18.   
    19.   
    20. int _tmain(int argc,_TCHAR* argv[])  
    21. {  
    22. cout<<"这是一个串行测试程序! ";  
    23. double start = omp_get_wtime( );//获取起始时间  
    24.   
    25. for(int i = 0; i < 10000; i++)  
    26. {   
    27. test();  
    28. }  
    29.   
    30. double end = omp_get_wtime( );  
    31.   
    32. cout<<"计算耗时为:"<<end -start<<" ";  
    33.   
    34. cin>>end;  
    35.   
    36. return 0;  
    37. }  
    #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<<"这是一个串行测试程序!
    ";
    double start = omp_get_wtime( );//获取起始时间
    
    for(int i = 0; i < 10000; i++)
    { 
    test();
    }
    
    double end = omp_get_wtime( );
    
    cout<<"计算耗时为:"<<end -start<<"
    ";
    
    cin>>end;
    
    return 0;
    }
    
    

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

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

    1. #include "stdafx.h"  
    2.   
    3. #include<omp.h>  
    4.   
    5. #include <iostream>  
    6.   
    7. using namespace std;  
    8.   
    9.   
    10. //循环测试函数  
    11. void test()  
    12. {  
    13. for(inti=0;i<10000;i++)  
    14. {  
    15.   
    16. }  
    17. }  
    18.   
    19. int _tmain(int argc, _TCHAR* argv[])  
    20. {  
    21. cout<<"这是一个并行测试程序! ";  
    22.   
    23. doublestart = omp_get_wtime( );//获取起始时间  
    24.   
    25.   
    26. #pragma ompparallel for  
    27. for(inti = 0; i < 10000; i++)   
    28. {  
    29. test();  
    30. }  
    31.   
    32.   
    33. doubleend = omp_get_wtime( );  
    34.   
    35. cout<<"计算耗时为:"<<end -start<<" ";  
    36.   
    37. cin>>end;  
    38.   
    39. return0;  
    40. }  
    #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<<"这是一个并行测试程序!
    ";
    
    doublestart = omp_get_wtime( );//获取起始时间
    
    
    #pragma ompparallel for
    for(inti = 0; i < 10000; i++) 
    {
    test();
    }
    
    
    doubleend = omp_get_wtime( );
    
    cout<<"计算耗时为:"<<end -start<<"
    ";
    
    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
    
       
    
    
  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/wuyida/p/6301371.html
Copyright © 2011-2022 走看看