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

				
时间: 2024-10-09 21:52:40

OpenCV中OpenMP的使用的相关文章

立体视觉-opencv中立体匹配相关代码

三种匹配算法比较 BM算法: 该算法代码: view plaincopy to clipboardprint? CvStereoBMState *BMState = cvCreateStereoBMState(); int SADWindowSize=15;    BMState->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 9;   BMState->minDisparity = 0;   BMState->number

opencv中的 HOGDescriptor 类

其定义在  object.hpp中找到的: [cpp] view plain copy struct CV_EXPORTS_W HOGDescriptor { public: enum { L2Hys=0 }; enum { DEFAULT_NLEVELS=64 }; CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8), cellSize(8,8), nbins(9), derivApertu

OpenCV中的Haar+Adaboost(五):AdaBoost之DAB与GAB

之前的文章主要讲解了OpenCV中与检测相关的内容,包括Haar特征.积分图和检测分类器结构:之后的文章将逐步开始介绍训练相关的内容.而本节主要介绍AdaBoost的理论,以及AdaBoost中的DAB与GAB算法,为后续讲解奠定基础. (一) AdaBoost背景介绍 在了解AdaBoost之前,先介绍弱学习和强学习的概念: 1. 弱学习:识别错误率小于1/2,即准确率仅比随机猜测略高的学习算法 2. 强学习:识别准确率很高并能在多项式时间内完成的学习算法 显然,无论对于任何分类问题,弱学习都

有关meanshift跟踪的理解(在opencv中实现)(转载)

meanshift算法思想其实很简单:利用概率密度的梯度爬升来寻找局部最优.它要做的就是输入一个在图像的范围,然后一直迭代(朝着重心迭代)直到满足你的要求为止.但是他是怎么用于做图像跟踪的呢?这是我自从学习meanshift以来,一直的困惑.而且网上也没有合理的解释.经过这几天的思考,和对反向投影的理解使得我对它的原理有了大致的认识. 在opencv中,进行meanshift其实很简单,输入一张图像(imgProb),再输入一个开始迭代的方框(windowIn)和一个迭代条件(criteria)

OpenCV中的矩阵乘法运算

转载:http://blog.csdn.net/tangwei2014 OpenCV中矩阵乘法运算 1. Mat*Mat: 第一个矩阵的列数必须等于第二个矩阵的行数. [0, 1, 2, 3;     [0, 0, 0;       [14, 14, 14; 0, 1, 2, 3; *  1, 1, 1;  =    14, 14, 14; 0, 1, 2, 3]      2, 2, 2;        14, 14, 14] 3, 3, 3] 2. Mat.mul(Mat): 两个矩阵维数必

OpenCV中feature2D学习——FAST特征点检测

在前面的文章<OpenCV中feature2D学习--SURF和SIFT算子实现特征点检测>中讲了利用SIFT和SURF算子进行特征点检测,这里尝试使用FAST算子来进行特征点检测. FAST的全名是:Features from Accelerated Segment Test,主要特点值计算速度快,比已知的其他特征点检测算法要快很多倍,可用于计算机视觉应用的实时场景.目前以其高计算效率(computational performance).高可重复性(highrepeatability)成为

opencv中值滤波和低通滤波器对椒盐噪声处理的效果比较

opencv中值滤波和低通滤波器对椒盐噪声处理的效果比较 效果: 通过比较我们可以看出,中值滤波器有很好的保留了图像的边界信息 代码: void showimage(const std::string &str,const cv::Mat &image){ namedWindow(str,CV_WINDOW_AUTOSIZE); imshow(str,image); } Mat salt(const cv::Mat &image,int n){ Mat result = image

OpenCV中图像的结构和区别

在OpenCV中,现在有很多种结构类型可以用来表示图像,它们之间有区别又有联系,现在记录一下它们之间的区别和相似之处,以便后面查看. 其中类型有: 1. Iplimage,2. Mat,3.CvMat, 4.CVArr: 其中: 1. IplImage: 较老版本的图像存储类型,在2.0之前使用: 2. CvArr: 也是较老的一种存储结构,是一种抽象的基类. 3. CvMat: 矩阵结构. 4. Mat:  新版本中使用的,推荐使用,是一个图像容器,基本上讲 Mat 是一个类,由两个数据部分组

对OpenCV中3种乘法操作的理解掌握

参考了<Opencv中Mat矩阵相乘--点乘.dot.mul运算详解 >"http://blog.csdn.net/dcrmg/article/details/52404580"的相关内容. 乘法是线性代数的基本操作,在OpenCV中有三种方法实现了乘法. 一.向量乘法 这两幅图像说明的就是向量乘法.在OpenCV中采用" . "来实现,要求是第一个矩阵的列值等于第二个矩阵的行值.且每个矩阵都是float结构. Mat A = Mat(3,3,CV_32