include/opencv2/gpu/matrix_operations.hpp
Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other GpuMaterials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_GPU_MATRIX_OPERATIONS_HPP__
00044 #define __OPENCV_GPU_MATRIX_OPERATIONS_HPP__
00045 
00046 namespace cv
00047 {
00048 
00049 namespace gpu
00050 {
00051 
00055 
00056 inline GpuMat::GpuMat() : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) {}
00057 
00058 inline GpuMat::GpuMat(int _rows, int _cols, int _type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
00059 {
00060     if( _rows > 0 && _cols > 0 )
00061         create( _rows, _cols, _type );
00062 }
00063 
00064 inline GpuMat::GpuMat(Size _size, int _type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
00065 {
00066     if( _size.height > 0 && _size.width > 0 )
00067         create( _size.height, _size.width, _type );
00068 }
00069 
00070 inline GpuMat::GpuMat(int _rows, int _cols, int _type, const Scalar& _s)
00071     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
00072 {
00073     if(_rows > 0 && _cols > 0)
00074     {
00075         create(_rows, _cols, _type);
00076         *this = _s;
00077     }
00078 }
00079 
00080 inline GpuMat::GpuMat(Size _size, int _type, const Scalar& _s)
00081     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
00082 {
00083     if( _size.height > 0 && _size.width > 0 )
00084     {
00085         create( _size.height, _size.width, _type );
00086         *this = _s;
00087     }
00088 }
00089 
00090 inline GpuMat::GpuMat(const GpuMat& m)
00091     : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend)
00092 {
00093     if( refcount )
00094         CV_XADD(refcount, 1);
00095 }
00096 
00097 inline GpuMat::GpuMat(int _rows, int _cols, int _type, void* _data, size_t _step)
00098     : flags(Mat::MAGIC_VAL + (_type & TYPE_MASK)), rows(_rows), cols(_cols), step(_step), data((uchar*)_data), refcount(0),
00099     datastart((uchar*)_data), dataend((uchar*)_data)
00100 {
00101     size_t minstep = cols*elemSize();
00102     if( step == Mat::AUTO_STEP )
00103     {
00104         step = minstep;
00105         flags |= Mat::CONTINUOUS_FLAG;
00106     }
00107     else
00108     {
00109         if( rows == 1 ) step = minstep;
00110         CV_DbgAssert( step >= minstep );
00111         flags |= step == minstep ? Mat::CONTINUOUS_FLAG : 0;
00112     }
00113     dataend += step*(rows-1) + minstep;
00114 }
00115 
00116 inline GpuMat::GpuMat(Size _size, int _type, void* _data, size_t _step)
00117     : flags(Mat::MAGIC_VAL + (_type & TYPE_MASK)), rows(_size.height), cols(_size.width),
00118     step(_step), data((uchar*)_data), refcount(0),
00119     datastart((uchar*)_data), dataend((uchar*)_data)
00120 {
00121     size_t minstep = cols*elemSize();
00122     if( step == Mat::AUTO_STEP )
00123     {
00124         step = minstep;
00125         flags |= Mat::CONTINUOUS_FLAG;
00126     }
00127     else
00128     {
00129         if( rows == 1 ) step = minstep;
00130         CV_DbgAssert( step >= minstep );
00131         flags |= step == minstep ? Mat::CONTINUOUS_FLAG : 0;
00132     }
00133     dataend += step*(rows-1) + minstep;
00134 }
00135 
00136 
00137 inline GpuMat::GpuMat(const GpuMat& m, const Range& rowRange, const Range& colRange)
00138 {
00139     flags = m.flags;
00140     step = m.step; refcount = m.refcount;
00141     data = m.data; datastart = m.datastart; dataend = m.dataend;
00142 
00143     if( rowRange == Range::all() )
00144         rows = m.rows;
00145     else
00146     {
00147         CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
00148         rows = rowRange.size();
00149         data += step*rowRange.start;
00150     }
00151 
00152     if( colRange == Range::all() )
00153         cols = m.cols;
00154     else
00155     {
00156         CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
00157         cols = colRange.size();
00158         data += colRange.start*elemSize();
00159         flags &= cols < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
00160     }
00161 
00162     if( rows == 1 )
00163         flags |= Mat::CONTINUOUS_FLAG;
00164 
00165     if( refcount )
00166         CV_XADD(refcount, 1);
00167     if( rows <= 0 || cols <= 0 )
00168         rows = cols = 0;
00169 }
00170 
00171 inline GpuMat::GpuMat(const GpuMat& m, const Rect& roi)
00172     : flags(m.flags), rows(roi.height), cols(roi.width),
00173     step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
00174     datastart(m.datastart), dataend(m.dataend)
00175 {
00176     flags &= roi.width < m.cols ? ~Mat::CONTINUOUS_FLAG : -1;
00177     data += roi.x*elemSize();
00178     CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
00179         0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
00180     if( refcount )
00181         CV_XADD(refcount, 1);
00182     if( rows <= 0 || cols <= 0 )
00183         rows = cols = 0;
00184 }
00185 
00186 inline GpuMat::GpuMat(const Mat& m)
00187 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) { upload(m); }
00188 
00189 inline GpuMat::~GpuMat() { release(); }
00190 
00191 inline GpuMat& GpuMat::operator = (const GpuMat& m)
00192 {
00193     if( this != &m )
00194     {
00195         if( m.refcount )
00196             CV_XADD(m.refcount, 1);
00197         release();
00198         flags = m.flags;
00199         rows = m.rows; cols = m.cols;
00200         step = m.step; data = m.data;
00201         datastart = m.datastart; dataend = m.dataend;
00202         refcount = m.refcount;
00203     }
00204     return *this;
00205 }
00206 
00207 inline GpuMat& GpuMat::operator = (const Mat& m) { upload(m); return *this; }
00208 
00209 template <class T> inline GpuMat::operator DevMem2D_<T>() const { return DevMem2D_<T>(rows, cols, (T*)data, step); }
00210 template <class T> inline GpuMat::operator PtrStep_<T>() const { return PtrStep_<T>(static_cast< DevMem2D_<T> >(*this)); }
00211 
00212 //CPP: void GpuMat::upload(const Mat& m);
00213 
00214  inline GpuMat::operator Mat() const
00215  {
00216      Mat m;
00217      download(m);
00218      return m;
00219  }
00220 
00221 //CPP void GpuMat::download(cv::Mat& m) const;
00222 
00223 inline GpuMat GpuMat::row(int y) const { return GpuMat(*this, Range(y, y+1), Range::all()); }
00224 inline GpuMat GpuMat::col(int x) const { return GpuMat(*this, Range::all(), Range(x, x+1)); }
00225 inline GpuMat GpuMat::rowRange(int startrow, int endrow) const { return GpuMat(*this, Range(startrow, endrow), Range::all()); }
00226 inline GpuMat GpuMat::rowRange(const Range& r) const { return GpuMat(*this, r, Range::all()); }
00227 inline GpuMat GpuMat::colRange(int startcol, int endcol) const { return GpuMat(*this, Range::all(), Range(startcol, endcol)); }
00228 inline GpuMat GpuMat::colRange(const Range& r) const { return GpuMat(*this, Range::all(), r); }
00229 
00230 inline GpuMat GpuMat::clone() const
00231 {
00232     GpuMat m;
00233     copyTo(m);
00234     return m;
00235 }
00236 
00237 //CPP void GpuMat::copyTo( GpuMat& m ) const;
00238 //CPP void GpuMat::copyTo( GpuMat& m, const GpuMat& mask  ) const;
00239 //CPP void GpuMat::convertTo( GpuMat& m, int rtype, double alpha=1, double beta=0 ) const;
00240 
00241 inline void GpuMat::assignTo( GpuMat& m, int type ) const
00242 {
00243     if( type < 0 )
00244         m = *this;
00245     else
00246         convertTo(m, type);
00247 }
00248 
00249 //CPP GpuMat& GpuMat::operator = (const Scalar& s);
00250 //CPP GpuMat& GpuMat::setTo(const Scalar& s, const GpuMat& mask=GpuMat());
00251 //CPP GpuMat GpuMat::reshape(int _cn, int _rows=0) const;
00252 inline void GpuMat::create(Size _size, int _type) { create(_size.height, _size.width, _type); }
00253 //CPP void GpuMat::create(int _rows, int _cols, int _type);
00254 //CPP void GpuMat::release();
00255 
00256 inline void GpuMat::swap(GpuMat& b)
00257 {
00258     std::swap( flags, b.flags );
00259     std::swap( rows, b.rows ); std::swap( cols, b.cols );
00260     std::swap( step, b.step ); std::swap( data, b.data );
00261     std::swap( datastart, b.datastart );
00262     std::swap( dataend, b.dataend );
00263     std::swap( refcount, b.refcount );
00264 }
00265 
00266 inline void GpuMat::locateROI( Size& wholeSize, Point& ofs ) const
00267 {
00268     size_t esz = elemSize(), minstep;
00269     ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
00270     CV_DbgAssert( step > 0 );
00271     if( delta1 == 0 )
00272         ofs.x = ofs.y = 0;
00273     else
00274     {
00275         ofs.y = (int)(delta1/step);
00276         ofs.x = (int)((delta1 - step*ofs.y)/esz);
00277         CV_DbgAssert( data == datastart + ofs.y*step + ofs.x*esz );
00278     }
00279     minstep = (ofs.x + cols)*esz;
00280     wholeSize.height = (int)((delta2 - minstep)/step + 1);
00281     wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
00282     wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
00283     wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
00284 }
00285 
00286 inline GpuMat& GpuMat::adjustROI( int dtop, int dbottom, int dleft, int dright )
00287 {
00288     Size wholeSize; Point ofs;
00289     size_t esz = elemSize();
00290     locateROI( wholeSize, ofs );
00291     int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
00292     int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
00293     data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
00294     rows = row2 - row1; cols = col2 - col1;
00295     if( esz*cols == step || rows == 1 )
00296         flags |= Mat::CONTINUOUS_FLAG;
00297     else
00298         flags &= ~Mat::CONTINUOUS_FLAG;
00299     return *this;
00300 }
00301 
00302 inline GpuMat GpuMat::operator()( Range rowRange, Range colRange ) const { return GpuMat(*this, rowRange, colRange); }
00303 inline GpuMat GpuMat::operator()( const Rect& roi ) const { return GpuMat(*this, roi); }
00304 
00305 inline bool GpuMat::isContinuous() const { return (flags & Mat::CONTINUOUS_FLAG) != 0; }
00306 inline size_t GpuMat::elemSize() const { return CV_ELEM_SIZE(flags); }
00307 inline size_t GpuMat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
00308 inline int GpuMat::type() const { return CV_MAT_TYPE(flags); }
00309 inline int GpuMat::depth() const { return CV_MAT_DEPTH(flags); }
00310 inline int GpuMat::channels() const { return CV_MAT_CN(flags); }
00311 inline size_t GpuMat::step1() const { return step/elemSize1(); }
00312 inline Size GpuMat::size() const { return Size(cols, rows); }
00313 inline bool GpuMat::empty() const { return data == 0; }
00314 
00315 inline uchar* GpuMat::ptr(int y)
00316 {
00317     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00318     return data + step*y;
00319 }
00320 
00321 inline const uchar* GpuMat::ptr(int y) const
00322 {
00323     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00324     return data + step*y;
00325 }
00326 
00327 template<typename _Tp> inline _Tp* GpuMat::ptr(int y)
00328 {
00329     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00330     return (_Tp*)(data + step*y);
00331 }
00332 
00333 template<typename _Tp> inline const _Tp* GpuMat::ptr(int y) const
00334 {
00335     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00336     return (const _Tp*)(data + step*y);
00337 }
00338 
00339 inline GpuMat GpuMat::t() const
00340 {
00341     GpuMat tmp;
00342     transpose(*this, tmp);
00343     return tmp;
00344 }
00345 
00346 static inline void swap( GpuMat& a, GpuMat& b ) { a.swap(b); }
00347 
00348 inline GpuMat createContinuous(int rows, int cols, int type)
00349 {
00350     GpuMat m;
00351     createContinuous(rows, cols, type, m);
00352     return m;
00353 }
00354 
00355 inline void createContinuous(Size size, int type, GpuMat& m)
00356 {
00357     createContinuous(size.height, size.width, type, m);
00358 }
00359 
00360 inline GpuMat createContinuous(Size size, int type)
00361 {
00362     GpuMat m;
00363     createContinuous(size, type, m);
00364     return m;
00365 }
00366 
00367 inline void ensureSizeIsEnough(Size size, int type, GpuMat& m)
00368 {
00369     ensureSizeIsEnough(size.height, size.width, type, m);
00370 }
00371 
00372 
00376 
00377 inline CudaMem::CudaMem()  : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(0) {}
00378 inline CudaMem::CudaMem(int _rows, int _cols, int _type, int _alloc_type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(0)
00379 {
00380     if( _rows > 0 && _cols > 0 )
00381         create( _rows, _cols, _type, _alloc_type);
00382 }
00383 
00384 inline CudaMem::CudaMem(Size _size, int _type, int _alloc_type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(0)
00385 {
00386     if( _size.height > 0 && _size.width > 0 )
00387         create( _size.height, _size.width, _type, _alloc_type);
00388 }
00389 
00390 inline CudaMem::CudaMem(const CudaMem& m) : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), refcount(m.refcount), datastart(m.datastart), dataend(m.dataend), alloc_type(m.alloc_type)
00391 {
00392     if( refcount )
00393         CV_XADD(refcount, 1);
00394 }
00395 
00396 inline CudaMem::CudaMem(const Mat& m, int _alloc_type) : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0), alloc_type(0)
00397 {
00398     if( m.rows > 0 && m.cols > 0 )
00399         create( m.size(), m.type(), _alloc_type);
00400 
00401     Mat tmp = createMatHeader();
00402     m.copyTo(tmp);
00403 }
00404 
00405 inline CudaMem::~CudaMem()
00406 {
00407     release();
00408 
00409 }
00410 
00411 inline CudaMem& CudaMem::operator = (const CudaMem& m)
00412 {
00413     if( this != &m )
00414     {
00415         if( m.refcount )
00416             CV_XADD(m.refcount, 1);
00417         release();
00418         flags = m.flags;
00419         rows = m.rows; cols = m.cols;
00420         step = m.step; data = m.data;
00421         datastart = m.datastart;
00422         dataend = m.dataend;
00423         refcount = m.refcount;
00424         alloc_type = m.alloc_type;
00425     }
00426     return *this;
00427 }
00428 
00429 inline CudaMem CudaMem::clone() const
00430 {
00431     CudaMem m(size(), type(), alloc_type);
00432     Mat to = m;
00433     Mat from = *this;
00434     from.copyTo(to);
00435     return m;
00436 }
00437 
00438 inline void CudaMem::create(Size _size, int _type, int _alloc_type) { create(_size.height, _size.width, _type, _alloc_type); }
00439 
00440 
00441 //CCP void CudaMem::create(int _rows, int _cols, int _type, int _alloc_type);
00442 //CPP void CudaMem::release();
00443 
00444 inline Mat CudaMem::createMatHeader() const { return Mat(size(), type(), data); }
00445 inline CudaMem::operator Mat() const { return createMatHeader(); }
00446 
00447 inline CudaMem::operator GpuMat() const { return createGpuMatHeader(); }
00448 //CPP GpuMat CudaMem::createGpuMatHeader() const;
00449 
00450 inline bool CudaMem::isContinuous() const { return (flags & Mat::CONTINUOUS_FLAG) != 0; }
00451 inline size_t CudaMem::elemSize() const { return CV_ELEM_SIZE(flags); }
00452 inline size_t CudaMem::elemSize1() const { return CV_ELEM_SIZE1(flags); }
00453 inline int CudaMem::type() const { return CV_MAT_TYPE(flags); }
00454 inline int CudaMem::depth() const { return CV_MAT_DEPTH(flags); }
00455 inline int CudaMem::channels() const { return CV_MAT_CN(flags); }
00456 inline size_t CudaMem::step1() const { return step/elemSize1(); }
00457 inline Size CudaMem::size() const { return Size(cols, rows); }
00458 inline bool CudaMem::empty() const { return data == 0; }
00459 
00461 // Arithmetical operations
00462 
00463 inline GpuMat operator ~ (const GpuMat& src)
00464 {
00465     GpuMat dst;
00466     bitwise_not(src, dst);
00467     return dst;
00468 }
00469 
00470 
00471 inline GpuMat operator | (const GpuMat& src1, const GpuMat& src2)
00472 {
00473     GpuMat dst;
00474     bitwise_or(src1, src2, dst);
00475     return dst;
00476 }
00477 
00478 
00479 inline GpuMat operator & (const GpuMat& src1, const GpuMat& src2)
00480 {
00481     GpuMat dst;
00482     bitwise_and(src1, src2, dst);
00483     return dst;
00484 }
00485 
00486 
00487 inline GpuMat operator ^ (const GpuMat& src1, const GpuMat& src2)
00488 {
00489     GpuMat dst;
00490     bitwise_xor(src1, src2, dst);
00491     return dst;
00492 }
00493 
00494 
00495 } /* end of namespace gpu */
00496 
00497 } /* end of namespace cv */
00498 
00499 #endif /* __OPENCV_GPU_MATRIX_OPERATIONS_HPP__ */