65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (16投票s)

2005 年 10 月 31 日

2分钟阅读

viewsIcon

118055

downloadIcon

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.libcv.libhighgui.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) 下载。

© . All rights reserved.