使用 MMX/SSE 扩展的类似 STL 的基于模板的编码






4.76/5 (16投票s)
2005 年 10 月 31 日
2分钟阅读

118055

669
使用 OpenCV、vigra 和 boost 的 MMX/SSE 扩展的类似 STL 的基于模板的编码。
引言
使用 MMX/SSE 扩展加速是图像处理、信号处理和数值计算中最有效的性能提升技术之一。 为了使用 MMX/SSE 加速您的应用程序,英特尔提供了以下解决方案
这些解决方案的组合是最佳解决方案。Open CV 是此组合的接口部分。然而,基于 OpenCV 的编码会导致混乱和难以理解的代码。基于类似 STL 代码包装 OpenCV 可以实现更复杂的 MMX/SSE 扩展编码。类似 STL 的 OpenCV 包装器 (STLLCV) 是 OpenCV 的包装,它支持类似 STL 的可读代码。此包装也是以下类似 STL 库的接口
以下是关于使用此包装的一些基本说明。
矩阵运算包装
uBLAS 是一种基于表达式模板技术的矩阵运算。表达式模板技术可以简单地描述复杂的矩阵运算。与 uBLAS 的接口支持使用各种 OpenCV 功能进行相同的简单描述。以下给出了此包装的用法。
用法
#include "stllcv/ublascvmatrix.hxx" using namespace stllcv; //init matrix CublasCvMatrix<float,3,3> A; A[0][0]=3; A[0][1]=2; A[0][2]=1; A[1][0]=1; A[1][1]=1; A[1][2]=4; A[2][0]=3; A[2][1]=2; A[2][2]=5; CublasCvMatrix<float,3,3> B; //Multiple as OpenCV matrix cvMatMul( &(CvMat)A , &(CvMat)A, &(CvMat) B ); //Mutiple as uBLAS matrix B =boost::numeric::ublas::prod (A,A);
有关此类的更多信息,请参见此处。
图像操作包装
VIGRA 接口
VIGRA 是一个类似 STL 的图像处理库。VIGRA 提供了各种 STL 风格的图像处理功能。 与 VIGRA 的接口支持使用各种 OpenCV 功能进行 STL 风格的图像处理。以下给出了此包装的用法。
用法
#include "vigra/transformimage.hxx" #include "vigra/recursiveconvolution.hxx" #include "stllcv/iplvbasicimageoperation.hxx" #include "stllcv/iplvbasicimage.hxx" #include "highgui.h" using namespace stllcv; #define PEXTYPE unsigned char int main(int argc, char * argv[]) { char winName[]="srcImg"; cvNamedWindow( winName, 1 ); CiplvBasicImage<PEXTYPE> iplvImage1("lena.jpg"); showIplvBasicImag<PEXTYPE>(&iplvImage1,winName); int width1 = iplvImage1.width(); int height1 =iplvImage1.height(); CiplvBasicImage<PEXTYPE> iplvImage2( width1*2 ,height1*2); std::fill(iplvImage2.begin(),iplvImage2.end(),100); iplRotate(iplvImage1.pIplImage, iplvImage2.pIplImage, 30.0, 100 ,150 ,IPL_INTER_NN); showIplvBasicImag<PEXTYPE>(&iplvImage2,winName); vigra::initImage( destIterRange( iplvImage2.upperLeft() + vigra::Diff2D(50, 100), iplvImage2.upperLeft() + vigra::Diff2D(400, 200)) ,200); showIplvBasicImag<PEXTYPE>(&iplvImage2,winName); vigra::transformImage(srcImageRange(iplvImage2), destImage(iplvImage2), vigra::linearIntensityTransform(-1, -255)); showIplvBasicImag<PEXTYPE>(&iplvImage2,winName); CiplvBasicImage<PEXTYPE> iplvImage3tmp( iplvImage2); CiplvBasicImage<PEXTYPE> iplvImage3( iplvImage2); int scale = 5; vigra::recursiveSmoothX(vigra::srcImageRange(iplvImage2), vigra::destImage(iplvImage3tmp), scale); vigra::recursiveSmoothY(vigra::srcImageRange(iplvImage3tmp), vigra::destImage(iplvImage3), scale); showIplvBasicImag<PEXTYPE>(&iplvImage3,winName); saveIplvBasicImag<PEXTYPE>(&iplvImage3, "out.jpg"); cvDestroyWindow(winName); return 0; }
有关此类的更多信息,请参见此处。
Adobe GIL 接口
Adobe GIL 也是一个类似 STL 的图像处理库。以下给出了我们包装的用法。
用法
#include "stllcv/gil_wrap_iplimage.hpp" #include <iostream> #include "cv.h" #include "stllcv/gil_dynamic_wrap_iplimage.hpp" //including this file icrease complie time #include "highgui.h" using namespace gil; using namespace stllcv; template <typename Out> struct halfdiff_cast_channels { template <typename T> Out operator()(const T& in1, const T& in2) const { return Out((in2-in1)/2);} }; template <typename SrcView, typename DstView> void x_gradient(const SrcView& src, const DstView& dst) { typedef typename DstView::channel_t dst_channel_t; for (int y=0; y<src.height(); ++y) { typename SrcView::x_iterator src_it = src.row_begin(y); typename DstView::x_iterator dst_it = dst.row_begin(y); for (int x=1; x<src.width()-1; ++x) { transform_channels(src_it[x-1], src_it[x+1], dst_it[x], halfdiff_cast_channels<dst_channel_t>());}} } template <typename DstView> struct x_gradient_obj { typedef void result_type; // required typedef const DstView& _dst; x_gradient_obj(const DstView& dst) : _dst(dst) {} template <typename SrcView> void operator()(const SrcView& src) const { x_gradient(src, _dst); } }; template <typename SrcViews, typename DstView> void x_gradient(any_image_view<SrcViews>& src, const DstView& dst) { apply_operation(src, x_gradient_obj<DstView>(dst)); } template<typename ImageClass> void show_image(ImageClass &image, char *win_name ) { cvShowImage( win_name, image.pIplImage ); std::cout << "Wait Key Input" << std::endl; cvWaitKey(0); } int main(int argc, unsigned char* argv[]) { char winName[]="srcImg"; cvNamedWindow( winName, 1 ); IplImage *gray_piplimg=cvLoadImage( "test.jpg", 0 ); IplImage *color_piplimg=cvLoadImage( "test.jpg"); int width=gray_piplimg->width; int height=gray_piplimg->height; int sub_width=115; int sub_height=113; //plz see type naming rule http://opensource.adobe.com/ // gil/html/giltutorial.html#AppendixConventionSec //static wrap rgb8_planar_view_t rgb8planarview1 = gil_view_from_iplimage<rgb8_planar_ptr_t >(color_piplimg); rgb8_planar_view_t rgb8planarview2 = gil_view_from_iplimage<planar_ptr<unsigned char *, rgb_t> >(color_piplimg); //planar_color is not supported in some OpenCV's functions. bgr8_view_t bgr8view1 = gil_view_from_iplimage<bgr8_ptr_t >(color_piplimg); //pixel<float ,bgr_t >* == bgr32f_pixel_t* == bgr32f_ptr_t bgr32f_view_t bgr32fview1 = gil_view_from_iplimage<bgr32f_ptr_t>(color_piplimg); bgr32f_view_t bgr32fview2 = gil_view_from_iplimage<bgr32f_pixel_t *>(color_piplimg); bgr32f_view_t bgr32fview3 = gil_view_from_iplimage<pixel<float , bgr_t >*>(color_piplimg); gil_wrap_iplimage<gray8_pixel_t*> graywrap1("test.jpg"); gil_wrap_iplimage<bgr8_ptr_t> colorwrap1(width,height); gil_wrap_iplimage<bgr8_ptr_t> colorwrap2(color_piplimg); std::copy(bgr8view1.begin(),bgr8view1.end(),colorwrap1.begin()); show_image(colorwrap1,winName); x_gradient(bgr8view1,(bgr8_view_t)colorwrap1); show_image(colorwrap1,winName); bgr8_view_t bgr_sub_view=subimage_view(bgr8view1, 20,30, sub_width, sub_height); gil_wrap_iplimage<bgr8_pixel_t *> color_sub_wrap1(sub_width , sub_height); std::copy(bgr_sub_view.begin(),bgr_sub_view.end(), color_sub_wrap1.begin()); show_image(color_sub_wrap1,winName); //dynamic wrap //detail of dynamic image http://opensource.adobe.com/ // gil/html/giltutorial.html#DynamicImageSec //This imp is based on gil::any_image_view any_ipl_image_view_t color_dynamic_view1( gil_dynamic_view_from_iplimage(color_piplimg)); gil_dynamic_wrap_iplimage<IplImage> color_dynamic_wrap1("test.jpg"); gil_dynamic_wrap_iplimage<IplImage> color_dynamic_wrap2(width,height); gil_dynamic_wrap_iplimage<IplImage> color_dynamic_wrap3(color_piplimg); x_gradient(*(color_dynamic_wrap3.any_image_view_ptr), (bgr8_view_t)colorwrap1); std::cout << "x_gradient_any_view_warp_class " << std::endl; show_image(colorwrap1,winName); cvReleaseImage( &gray_piplimg ); cvReleaseImage( &color_piplimg ); return 0; }
使用 stllcv
使用下载的文件
- 将 OpenCV 安装到C:\Program Files\OpenCV
- 将 boost 1.33.1 安装到C:\lib\boost_1_33_1
- 将 vigra 1.4.0 安装到C:\lib\vigra1.4.0
- 将 adobe::GIL 安装到C:\lib\adobe\gil
- 将下载的文件stllcv_0_7_7.zip 解压缩到C:\lib\stllcv_0_7_7
- 打开C:\lib\stllcv_0_7_7\src\stllcv_vs2003.sln
- 您可以看到以上示例的项目
在您的项目中使用 stllcv
- 安装 OpenCV 并添加其包含路径 (C:\Program Files\OpenCV\cv\include; C:\Program Files\OpenCV\cxcore\include; C:\Program Files\OpenCV\otherlibs\highgui (和 C:\Program Files\Intel\plsuite\ (如果安装了 ipl 则包含)))
- 添加 OpenCV 的 libpath (C:\Program Files\OpenCV\lib) 并添加指向 cxcore.lib、cv.lib、highgui.lib 的链接,(如果安装了 ipl,则为 ipl.lib)
- 安装 boost 并添加其包含路径 (C:\lib\boost_1_33_1)
- 安装 vigra 并添加其包含路径 (C:\lib\vigra1.4.0\include)
- 安装 adobe::GIL 并添加其包含路径 (C:\lib\adobe\gil\gil)
- 解压缩下载的文件stllcv_0_7_7.zip 并添加包含路径 (C:\lib\stllcv_0_7_7\include)
- 基于以上示例包含适当的头文件
- 然后您可以在您的项目中使用各种包装类和函数
当前版本的 stllcv 可以从类似 STL 的 OpenCV 包装器 (STLLCV) 下载。