Click here to Skip to main content
15,861,168 members
Articles / Programming Languages / C++
Article

STL like template based coding with the MMX/SSE extension

Rate me:
Please Sign up or sign in to vote.
4.76/5 (17 votes)
17 Nov 20062 min read 113.4K   669   45   18
STL like template based coding with the MMX/SSE extension using OpenCV, vigra, and boost.

Introduction

Accelerating with MMX/SSE extension is one of the most effective performance gain techniques in image processing, signal processing and numerical computing. To accelerate your application with MMX/SSE, Intel provides the following solutions:

A combination of these solutions is the best solution. Open CV is the interface part of this combination. However, coding based on OpenCV causes messy and unreadable code. More sophisticated coding with MMX/SSE extension can be achieved by wrapping OpenCV based on STL like code. STL like OpenCV wrapper (STLLCV) is a wrapping of OpenCV which enables STL like readable code. This wrapping is also an interface to the following STL like libraries:

The following are belief explanations about the usage of this wrapping.

Matrix operation wrapping

uBLAS is a matrix operation based on expressional template technique. Expressional template technique enables simple description of complicated matrix operations. The interface to uBLAS enables the same simple description with various OpenCV vraioue functions. The usage of this wrapping is given below.

Usage

#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);

See here, for more information on this class.

Image operation wrapping

Interface to vigra

VIGRA is a STL like image processing library. VIGRA provides various STL style image processing functions. This interface to VIGRA enables STL style image processing with various OpenCV variouse functions. The usage of this wrapping is given below.

Usage

#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;
}

See here, for more information on this class.

Interface to adobe GIL

Adobe GIL is also STL like image processing library. Usage of our wrapping is given below.

Usage

#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;
}

Using stllcv

Using downloaded file

  • Install OpenCV to C:\Program Files\OpenCV
  • Install boost 1.33.1 to C:\lib\boost_1_33_1
  • Install vigra 1.4.0 to C:\lib\vigra1.4.0
  • Install adobe::GIL to C:\lib\adobe\gil
  • Unpack downloaded file stllcv_0_7_7.zip to C:\lib\stllcv_0_7_7
  • Open C:\lib\stllcv_0_7_7\src\stllcv_vs2003.sln
  • You can see projects of above examples

Using stllcv with your project

  • Install OpenCV and add its include path (C:\Program Files\OpenCV\cv\include; C:\Program Files\OpenCV\cxcore\include; C:\Program Files\OpenCV\otherlibs\highgui (and C:\Program Files\Intel\plsuite\ (include if you have ipl))
  • Add OpenCV's libpath (C:\Program Files\OpenCV\lib) and add links to cxcore.lib, cv.lib, highgui.lib, (ipl.lib if you have ipl)
  • Install boost and add its include path (C:\lib\boost_1_33_1)
  • Install vigra and add its include path (C:\lib\vigra1.4.0\include)
  • Install adobe::GIL and add its include path (C:\lib\adobe\gil\gil)
  • Unpack downloaded file stllcv_0_7_7.zip and add the include path (C:\lib\stllcv_0_7_7\include)
  • Include appropriate header files based on above examples
  • Then you can use various wrapping class and functions with your project

The current version of stllcv can be downloaded from STL like OpenCV wrapper (STLLCV).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Japan Japan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalpixel type from iterator [modified] Pin
CoffeeBuzz22-Jun-07 3:01
CoffeeBuzz22-Jun-07 3:01 
GeneralRe: pixel type from iterator Pin
Hirotaka Niitsuma17-Oct-07 18:14
Hirotaka Niitsuma17-Oct-07 18:14 
GeneralSmall Problem: Dealloc Error Pin
RedFraggle24-Nov-06 8:25
RedFraggle24-Nov-06 8:25 
GeneralRe: Small Problem: Dealloc Error [modified] Pin
Hirotaka Niitsuma24-Nov-06 23:23
Hirotaka Niitsuma24-Nov-06 23:23 
QuestionIPL outdated, how to use ippi? (link error for ipl.lib) Pin
RedFraggle14-Nov-06 1:42
RedFraggle14-Nov-06 1:42 
AnswerRe: IPL outdated, how to use ippi? (link error for ipl.lib) Pin
Hirotaka Niitsuma14-Nov-06 15:06
Hirotaka Niitsuma14-Nov-06 15:06 
GeneralSubversion enabled Pin
Hirotaka Niitsuma5-Nov-06 3:02
Hirotaka Niitsuma5-Nov-06 3:02 
GeneralOpenCV wraped by adobe::gil Pin
Hirotaka Niitsuma3-Nov-06 4:44
Hirotaka Niitsuma3-Nov-06 4:44 
GeneralRe: OpenCV wraped by adobe::gil Pin
Hirotaka Niitsuma3-Nov-06 14:35
Hirotaka Niitsuma3-Nov-06 14:35 
GeneralBoost community will accept GIL instead of vigra Pin
Hirotaka Niitsuma31-Oct-06 16:35
Hirotaka Niitsuma31-Oct-06 16:35 
Generalcurrent version [modified] Pin
Hirotaka Niitsuma11-Jul-06 21:34
Hirotaka Niitsuma11-Jul-06 21:34 
GeneralI wish I could vote again !! Pin
WREY31-Oct-05 17:17
WREY31-Oct-05 17:17 
GeneralRe: I wish I could vote again !! Pin
Hirotaka Niitsuma1-Nov-05 21:42
Hirotaka Niitsuma1-Nov-05 21:42 
GeneralIt would have been great ... Pin
WREY31-Oct-05 9:27
WREY31-Oct-05 9:27 
GeneralRe: It would have been great ... Pin
Hirotaka Niitsuma31-Oct-05 15:17
Hirotaka Niitsuma31-Oct-05 15:17 
GeneralCould you fix the horizontal scrolling problem! Pin
WREY31-Oct-05 2:02
WREY31-Oct-05 2:02 
GeneralRe: Could you fix the horizontal scrolling problem! Pin
Mircea Puiu31-Oct-05 4:36
Mircea Puiu31-Oct-05 4:36 
GeneralRe: Could you fix the horizontal scrolling problem! Pin
Hirotaka Niitsuma31-Oct-05 15:20
Hirotaka Niitsuma31-Oct-05 15:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.