opencv2.2.0源代码(include文件)分析(4)

3  modules\core\include\opencv2\core\wimage.hpp

这个需要头文件 #include  “opencv2/core/core_c.h”

///

图像类提供了一个关于IplImage的底层类结构,此类是为了实现:

1,所有的数据都有一个精确用户归属,以避免内存泄露(memoryleaks)

2,不为行为隐藏配置和备份

3,提供一个简单的接口,连接OpenCV函数(满足所有的IPP)

4,可以很容易将额外的数据作为图像处理

5,可以很容易创建属于其他图像的子图像

6,快速的像素处理,在编译时间内对处理多通道很有用处

WImage类,是图像类提供的数据存储器。’W’来自封装器”wrapper”,但不方便于IplImage类。WImage类可以使用WImageBuffer类配置和释放数据,或者使用WImageView类组织子图或者观察额外的数据。View类不进行内存配置,每一个类有两版本:当在编译时通道数已知时,和通道数未知。使用特定的通道数(即作为一个常量)可以提供最优化编译时间。

我们使用(c,r),c指column c,r指row r。(c,r)=(0,0)指左上角。这类似于欧几里得坐标标准(即满足右手定则)。

故(c,r)常常指[0,width]*[0,height]

用法实例:

WImageBuffer3_bim(5,7); //生成一个5*7 3通道 uchar类图像

WImageView3_bsub_im(im, 2,2, 3,3); //3*3 子矩阵

Vector<float>vec(10, 3.0f);

WImageView1_fuser_im(&vec[0],2,5); //2*5 图像 w/提供数据

im.SetZero();//类似于cvSetZero(im.Ip1())

*im(2,3)=15;//修改2行3列的数据

MySetRand(&sub_im);

 

//复制第二行道第一行,不使用内存完成

//配置和使用SSE,如果IPP可用

intw = im.Width();

im.View(0,0,w,1).CopyFrom(im.View(0,1, w,1));

 

//使用WImage后,不关心数据来源

voidMySetRand(WImage_b* im)

{// 使用任意通道

   for(int r = 0; r < im->Height(); ++r) {

     float*row = im->Row(r);

     for(int c = 0; c < im->Width(); ++c) {

        for(int ch = 0; ch < im->Channels(); ++ch, ++row) {

          *row= uchar(rand() & 255);

        }

     }

   }

 }

这些函数不是OpenCV中图像allocation,viewing和access的基本函数,除了一些在wimage_util.h也可以找到的有用的函数

此头文件,是在CV命名空间内,定义了含有一个参数的模板类:WImage,WImageBuffer, WImageView;和含有两个参数的模板类:WImageC,WImageBufferC, WImageViewC。和相应的一些typedef定义。以下为这些模板类声明定义的详细描述

1,WImage

此类是连接数据的接口。可以被WImageBuffer类allocate数据,或者被WImageView类指向子图或者outside 数据,组织。

此类是个虚基类,所以不能实例化对象,只能用作派生。一些基本成员定义:public类成员定义int Width(), intHeight(), int WidthStep(), int Channels(), int ChannelSize(), int PixelSize(),int Depth(), inline T* Row(int r), inline T* operator()(int c, int r), voidCopyFrom(const WImage<T>& src), void SetZero(), WImageView<T>View(int c, int r, int width, int height);protected成员定义(不允许复制和操作)WImage(constWImage&),  void operator=(const WImage&),   explicitWImage(IplImage* img) : image_(img) ,   void SetIpl(IplImage*image) ,     IplImage* image_;

 

                2,WImageC

此类继承于WImage,也是抽象类。适合像素类型和通道数在编译时已知情况:此封转器可以加速类如访问单个像素等的操作。

Public类成员包括:WImageViewC<T,C> View(int c, int r, int width, int height), void CopyFrom(constWImageC<T, C>& src), int Channels();protected类成员(不允许被复制和操作)包括:WImageC(constWImageC &), void operator=(const WImageC&), void SetIpl(IplImage*image)

 

                3,WImageBuffer

此类继承于WImage,此类的图拥有数据,可以被allocated和freed,但是不允许复制,但可以克隆。

Public类成员包括:void Allocate(intwidth, int height, int nchannels), void SetIpl(IplImage* img), voidcloneFrom(const WImage<T>& src), void ReleaseImage(), bool IsNull();private类成员包括:WImageBuffer(constWImageBuffer&),    voidoperator=(const WImageBuffer&)

 

                4,WImageBufferC

此类继承于WImageC,类似WImageBuffer,但是此类属于通道数已知的情况下。

Public类成员包括:void Allocate(intwidth, int height), void SetIpl(IplImage* img), void CloneFrom(constWImageC<T, C>& src), void ReleaseImage(), bool IsNull()。Private类成员包括WImageBufferC(constWImageBufferC&),  voidoperator=(const WImageBufferC&);

 

                5,WImageView

此类继承于WImage,用于查看允许将子图作为整个图或者其他数据作为图的图。

Public类成员包括:WImageView(WImage<T>*img, int c, int r, int width, int height), WImageView(T* data, int width, intheight, int channels, int width_step=-1), WImageView(IplImage*img):WImage<T>(img), WImageView(const WImage<T>&img):WImage<T>(0), WImageView& operator=(const WImage<T>&img);Protected类成员包括:IplImage header_

 

                6,WImageViewC

此类继承于WImageC,类似于WImageView,是抽象类。

Public类成员包括:主要是不同构造函数定义。Protected类成员包括: IplImage header_。

 

namespace cv{

 

template <typename T> class WImage;

template <typename T> class WImageBuffer;

template <typename T> class WImageView;

 

template<typename T, int C> class WImageC;

template<typename T, int C> class WImageBufferC;

template<typename T, int C> class WImageViewC;

 

//Commonly used typedefs.

typedef WImage<uchar>            WImage_b;

typedef WImageView<uchar>        WImageView_b;

typedef WImageBuffer<uchar>      WImageBuffer_b;

 

typedef WImageC<uchar,1>        WImage1_b;

typedef WImageViewC<uchar,1>    WImageView1_b;

typedef WImageBufferC<uchar,1>  WImageBuffer1_b;

 

typedef WImageC<uchar,3>        WImage3_b;

typedef WImageViewC<uchar,3>    WImageView3_b;

typedef WImageBufferC<uchar,3>  WImageBuffer3_b;

 

typedef WImage<float>            WImage_f;

typedef WImageView<float>        WImageView_f;

typedef WImageBuffer<float>      WImageBuffer_f;

 

typedef WImageC<float,1>        WImage1_f;

typedef WImageViewC<float,1>    WImageView1_f;

typedef WImageBufferC<float,1>  WImageBuffer1_f;

 

typedef WImageC<float,3>        WImage3_f;

typedef WImageViewC<float,3>    WImageView3_f;

typedef WImageBufferC<float,3>  WImageBuffer3_f;

 

//There isn't a standard for signed and unsigned short so be more

//explicit in the typename for these cases.

typedef WImage<short>            WImage_16s;

typedef WImageView<short>        WImageView_16s;

typedef WImageBuffer<short>      WImageBuffer_16s;

 

typedef WImageC<short,1>        WImage1_16s;

typedef WImageViewC<short,1>    WImageView1_16s;

typedef WImageBufferC<short,1>  WImageBuffer1_16s;

 

typedef WImageC<short,3>        WImage3_16s;

typedef WImageViewC<short,3>    WImageView3_16s;

typedef WImageBufferC<short,3>  WImageBuffer3_16s;

 

typedef WImage<ushort>            WImage_16u;

typedef WImageView<ushort>        WImageView_16u;

typedef WImageBuffer<ushort>      WImageBuffer_16u;

 

typedef WImageC<ushort,1>        WImage1_16u;

typedef WImageViewC<ushort,1>    WImageView1_16u;

typedef WImageBufferC<ushort,1>  WImageBuffer1_16u;

 

typedef WImageC<ushort,3>        WImage3_16u;

typedef WImageViewC<ushort,3>    WImageView3_16u;

typedef WImageBufferC<ushort,3>  WImageBuffer3_16u;

 

//

//WImage definitions

//

//This WImage class gives access to the data it refers to.  It can be

//constructed either by allocating the data with a WImageBuffer class or

//using the WImageView class to refer to a subimage or outside data.

template<typename T>

class WImage

{

public:

    typedef TBaseType;

 

    //WImage is an abstract class with no other virtual methods so make the

    //destructor virtual.

    virtual ~WImage()= 0;

 

    //Accessors

    IplImage*Ipl() {return image_; }

    const IplImage*Ipl() const {return image_; }

    T*ImageData() { return reinterpret_cast<T*>(image_->imageData);}

    const T*ImageData() const {

        return reinterpret_cast<const T*>(image_->imageData);

    }

 

    int Width() const {return image_->width;}

    int Height() const {return image_->height;}

 

    //WidthStep is the number of bytes to go to the pixel with the next y coord

    int WidthStep() const {return image_->widthStep;}

 

    int Channels() const {return image_->nChannels;}

    int ChannelSize() const {return sizeof(T);}  // number of bytes per channel

 

    //Number of bytes per pixel

    int PixelSize() const {return Channels()* ChannelSize(); }

 

    //Return depth type (e.g. IPL_DEPTH_8U, IPL_DEPTH_32F) which is the number

    //of bits per channel and with the signed bit set.

    //This is known at compile time using specializations.

    int Depth() const;

 

    inline const T*Row(int r) const {

        return reinterpret_cast<T*>(image_->imageData+ r*image_->widthStep);

    }

 

    inline T*Row(int r) {

        return reinterpret_cast<T*>(image_->imageData+ r*image_->widthStep);

    }

 

    //Pixel accessors which returns a pointer to the start of the channel

    inline T* operator()(int c, int r)  {

        return reinterpret_cast<T*>(image_->imageData+ r*image_->widthStep) +

            c*Channels();

    }

 

    inline const T* operator()(int c, int r) const  {

        return reinterpret_cast<T*>(image_->imageData+ r*image_->widthStep) +

            c*Channels();

    }

 

    //Copy the contents from another image which is just a convenience to cvCopy

    void CopyFrom(const WImage<T>&src) { cvCopy(src.Ipl(), image_); }

 

    //Set contents to zero which is just a convenient to cvSetZero

    void SetZero(){ cvSetZero(image_); }

 

    //Construct a view into a region of this image

    WImageView<T>View(int c, int r, int width, int height);

 

protected:

    //Disallow copy and assignment

    WImage(const WImage&);

    void operator=(const WImage&);

 

    explicit WImage(IplImage*img) : image_(img) {

        assert(!img|| img->depth == Depth());

    }

 

    void SetIpl(IplImage*image) {

        assert(!image|| image->depth == Depth());

        image_= image;

    }

 

    IplImage*image_;

};

 

 

 

//Image class when both the pixel type and number of channels

//are known at compile time.  This wrapper will speed up some of theoperations

//like accessing individual pixels using the () operator.

template<typename T, int C>

class WImageC: public WImage<T>

{

public:

    typedef typename WImage<T>::BaseTypeBaseType;

    enum {kChannels = C };

 

    explicit WImageC(IplImage*img) : WImage<T>(img) {

        assert(!img|| img->nChannels == Channels());

    }

 

    //Construct a view into a region of this image

    WImageViewC<T,C> View(int c, int r, int width, int height);

 

    //Copy the contents from another image which is just a convenience to cvCopy

    void CopyFrom(const WImageC<T,C>& src) {

        cvCopy(src.Ipl(),WImage<T>::image_);

    }

 

    //WImageC is an abstract class with no other virtual methods so make the

    //destructor virtual.

    virtual ~WImageC()= 0;

 

    int Channels() const {return C;}

 

protected:

    //Disallow copy and assignment

    WImageC(const WImageC&);

    void operator=(const WImageC&);

 

    void SetIpl(IplImage*image) {

        assert(!image|| image->depth == WImage<T>::Depth());

        WImage<T>::SetIpl(image);

    }

};

 

//

//WImageBuffer definitions

//

//Image class which owns the data, so it can be allocated and is always

//freed.  It cannot be copied but can be explicity cloned.

//

template<typename T>

class WImageBuffer: public WImage<T>

{

public:

    typedef typename WImage<T>::BaseTypeBaseType;

 

    //Default constructor which creates an object that can be

    WImageBuffer(): WImage<T>(0) {}

 

    WImageBuffer(int width, int height, int nchannels): WImage<T>(0) {

        Allocate(width,height, nchannels);

    }

 

    //Constructor which takes ownership of a given IplImage so releases

    //the image on destruction.

    explicit WImageBuffer(IplImage*img) : WImage<T>(img) {}

 

    //Allocate an image.  Does nothing if current size is the same as

    //the new size.

    void Allocate(int width, int height, int nchannels);

 

    //Set the data to point to an image, releasing the old data

    void SetIpl(IplImage*img) {

        ReleaseImage();

        WImage<T>::SetIpl(img);

    }

 

    //Clone an image which reallocates the image if of a different dimension.

    void CloneFrom(const WImage<T>&src) {

        Allocate(src.Width(),src.Height(), src.Channels());

        CopyFrom(src);

    }

 

    ~WImageBuffer(){

        ReleaseImage();

    }

 

    //Release the image if it isn't null.

    void ReleaseImage(){

        if (WImage<T>::image_){

            IplImage*image = WImage<T>::image_;

            cvReleaseImage(&image);

            WImage<T>::SetIpl(0);

        }

    }

 

    bool IsNull() const {return WImage<T>::image_== NULL; }

 

private:

    //Disallow copy and assignment

    WImageBuffer(const WImageBuffer&);

    void operator=(const WImageBuffer&);

};

 

//Like a WImageBuffer class but when the number of channels is known

//at compile time.

template<typename T, int C>

class WImageBufferC: public WImageC<T, C>

{

public:

    typedef typename WImage<T>::BaseTypeBaseType;

    enum {kChannels = C };

 

    //Default constructor which creates an object that can be

    WImageBufferC(): WImageC<T, C>(0) {}

 

    WImageBufferC(int width, int height): WImageC<T, C>(0) {

        Allocate(width,height);

    }

 

    //Constructor which takes ownership of a given IplImage so releases

    //the image on destruction.

    explicit WImageBufferC(IplImage*img) : WImageC<T, C>(img) {}

 

    //Allocate an image.  Does nothing if current size is the same as

    //the new size.

    void Allocate(int width, int height);

 

    //Set the data to point to an image, releasing the old data

    void SetIpl(IplImage*img) {

        ReleaseImage();

        WImageC<T,C>::SetIpl(img);

    }

 

    //Clone an image which reallocates the image if of a different dimension.

    void CloneFrom(const WImageC<T,C>& src) {

        Allocate(src.Width(),src.Height());

        CopyFrom(src);

    }

 

    ~WImageBufferC(){

        ReleaseImage();

    }

 

    //Release the image if it isn't null.

    void ReleaseImage(){

        if (WImage<T>::image_){

            IplImage*image = WImage<T>::image_;

            cvReleaseImage(&image);

            WImageC<T,C>::SetIpl(0);

        }

    }

 

    bool IsNull() const {return WImage<T>::image_== NULL; }

 

private:

    //Disallow copy and assignment

    WImageBufferC(const WImageBufferC&);

    void operator=(const WImageBufferC&);

};

 

//

//WImageView definitions

//

//View into an image class which allows treating a subimage as an image

//or treating external data as an image

//

template<typename T>

class WImageView: public WImage<T>

{

public:

    typedef typename WImage<T>::BaseTypeBaseType;

 

    //Construct a subimage.  No checks are done that the subimage lies

    //completely inside the original image.

    WImageView(WImage<T>*img, int c, int r, int width, int height);

 

    //Refer to external data.

    //If not given width_step assumed to be same as width.

    WImageView(T*data, int width, int height, int channels, intwidth_step= -1);

 

    //Refer to external data.  This does NOT take ownership

    //of the supplied IplImage.

    WImageView(IplImage*img) : WImage<T>(img) {}

 

    //Copy constructor

    WImageView(const WImage<T>&img) : WImage<T>(0) {

        header_= *(img.Ipl());

        WImage<T>::SetIpl(&header_);

    }

 

    WImageView& operator=(const WImage<T>&img) {

        header_= *(img.Ipl());

        WImage<T>::SetIpl(&header_);

        return *this;

    }

 

protected:

    IplImageheader_;

};

 

 

template<typename T, int C>

class WImageViewC: public WImageC<T, C>

{

public:

    typedef typename WImage<T>::BaseTypeBaseType;

    enum {kChannels = C };

 

    //Default constructor needed for vectors of views.

    WImageViewC();

 

    virtual ~WImageViewC(){}

 

    //Construct a subimage.  No checks are done that the subimage lies

    //completely inside the original image.

    WImageViewC(WImageC<T,C>* img,

        int c, int r, int width, int height);

 

    //Refer to external data

    WImageViewC(T*data, int width, int height, int width_step =-1);

 

    //Refer to external data.  This does NOT take ownership

    //of the supplied IplImage.

    WImageViewC(IplImage*img) : WImageC<T, C>(img) {}

 

    //Copy constructor which does a shallow copy to allow multiple views

    //of same data.  gcc-4.1.1 gets confused if both versions of

    //the constructor and assignment operator are not provided.

    WImageViewC(const WImageC<T,C>& img) : WImageC<T, C>(0) {

        header_= *(img.Ipl());

        WImageC<T,C>::SetIpl(&header_);

    }

    WImageViewC(const WImageViewC<T,C>& img) : WImageC<T, C>(0) {

        header_= *(img.Ipl());

        WImageC<T,C>::SetIpl(&header_);

    }

 

    WImageViewC& operator=(const WImageC<T,C>& img) {

        header_= *(img.Ipl());

        WImageC<T,C>::SetIpl(&header_);

        return *this;

    }

    WImageViewC& operator=(const WImageViewC<T,C>& img) {

        header_= *(img.Ipl());

        WImageC<T,C>::SetIpl(&header_);

        return *this;

    }

 

protected:

    IplImageheader_;

};

 

 

//Specializations for depth

template<>

inline int WImage<uchar>::Depth() const {return IPL_DEPTH_8U;}

template<>

inline int WImage<signed char>::Depth() const {return IPL_DEPTH_8S;}

template<>

inline int WImage<short>::Depth() const {return IPL_DEPTH_16S;}

template<>

inline int WImage<ushort>::Depth() const {return IPL_DEPTH_16U;}

template<>

inline int WImage<int>::Depth() const {return IPL_DEPTH_32S;}

template<>

inline int WImage<float>::Depth() const {return IPL_DEPTH_32F;}

template<>

inline int WImage<double>::Depth() const {return IPL_DEPTH_64F;}

 

//

//Pure virtual destructors still need to be defined.

//

template<typename T> inline WImage<T>::~WImage(){}

template<typename T, int C> inline WImageC<T,C>::~WImageC() {}

 

//

//Allocate ImageData

//

template<typename T>

inline void WImageBuffer<T>::Allocate(int width, int height, intnchannels)

{

    if (IsNull()|| WImage<T>::Width() != width ||

        WImage<T>::Height()!= height || WImage<T>::Channels() != nchannels) {

        ReleaseImage();

        WImage<T>::image_= cvCreateImage(cvSize(width, height),

            WImage<T>::Depth(),nchannels);

    }

}

 

template<typename T, int C>

inline void WImageBufferC<T,C>::Allocate(int width, int height)

{

    if (IsNull()|| WImage<T>::Width() != width || WImage<T>::Height() != height) {

        ReleaseImage();

        WImageC<T,C>::SetIpl(cvCreateImage(cvSize(width, height),WImage<T>::Depth(),C));

    }

}

 

//

//ImageView methods

//

template<typename T>

WImageView<T>::WImageView(WImage<T>*img, int c, int r, int width,int height)

        :WImage<T>(0)

{

    header_= *(img->Ipl());

    header_.imageData= reinterpret_cast<char*>((*img)(c, r));

    header_.width= width;

    header_.height= height;

    WImage<T>::SetIpl(&header_);

}

 

template<typename T>

WImageView<T>::WImageView(T*data, int width, int height, intnchannels, int width_step)

          :WImage<T>(0)

{

    cvInitImageHeader(&header_,cvSize(width, height), WImage<T>::Depth(), nchannels);

    header_.imageData= reinterpret_cast<char*>(data);

    if (width_step> 0) {

        header_.widthStep= width_step;

    }

    WImage<T>::SetIpl(&header_);

}

 

template<typename T, int C>

WImageViewC<T,C>::WImageViewC(WImageC<T, C>* img, int c, int r, intwidth, int height)

        :WImageC<T, C>(0)

{

    header_= *(img->Ipl());

    header_.imageData= reinterpret_cast<char*>((*img)(c, r));

    header_.width= width;

    header_.height= height;

    WImageC<T,C>::SetIpl(&header_);

}

 

template<typename T, int C>

WImageViewC<T,C>::WImageViewC() : WImageC<T, C>(0) {

    cvInitImageHeader(&header_,cvSize(0, 0), WImage<T>::Depth(), C);

    header_.imageData= reinterpret_cast<char*>(0);

    WImageC<T,C>::SetIpl(&header_);

}

 

template<typename T, int C>

WImageViewC<T,C>::WImageViewC(T* data, int width, int height, intwidth_step)

    :WImageC<T, C>(0)

{

    cvInitImageHeader(&header_,cvSize(width, height), WImage<T>::Depth(), C);

    header_.imageData= reinterpret_cast<char*>(data);

    if (width_step> 0) {

        header_.widthStep= width_step;

    }

    WImageC<T,C>::SetIpl(&header_);

}

 

//Construct a view into a region of an image

template<typename T>

WImageView<T>WImage<T>::View(int c, int r, int width, int height){

    return WImageView<T>(this,c, r, width, height);

}

 

template<typename T, int C>

WImageViewC<T,C> WImageC<T, C>::View(int c, int r, int width, intheight){

    return WImageViewC<T,C>(this, c, r, width, height);

}

 

}  //end of namespace

 

#endif //__cplusplus

 

#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值