itom 1.4.0
|
00001 /* ******************************************************************** 00002 itom software 00003 URL: http://www.uni-stuttgart.de/ito 00004 Copyright (C) 2013, Institut für Technische Optik (ITO), 00005 Universität Stuttgart, Germany 00006 00007 This file is part of itom and its software development toolkit (SDK). 00008 00009 itom is free software; you can redistribute it and/or modify it 00010 under the terms of the GNU Library General Public Licence as published by 00011 the Free Software Foundation; either version 2 of the Licence, or (at 00012 your option) any later version. 00013 00014 In addition, as a special exception, the Institut für Technische 00015 Optik (ITO) gives you certain additional rights. 00016 These rights are described in the ITO LGPL Exception version 1.0, 00017 which can be found in the file LGPL_EXCEPTION.txt in this package. 00018 00019 itom is distributed in the hope that it will be useful, but 00020 WITHOUT ANY WARRANTY; without even the implied warranty of 00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library 00022 General Public Licence for more details. 00023 00024 You should have received a copy of the GNU Library General Public License 00025 along with itom. If not, see <http://www.gnu.org/licenses/>. 00026 *********************************************************************** */ 00027 00028 #ifndef __DATAOBJH 00029 #define __DATAOBJH 00030 00031 #include "defines.h" 00032 00033 //#include <crtdbg.h> 00034 #include <cstdlib> 00035 #include <iostream> 00036 #include <complex> 00037 #include <limits> 00038 #include <string> 00039 00040 #if !linux 00041 #pragma warning(disable:4996) 00042 #endif 00043 00044 #define NOMINMAX //see: http://social.msdn.microsoft.com/Forums/sv/vclanguage/thread/d986a370-d856-4f9e-9f14-53f3b18ab63e, this is only an issue with OpenCV 2.4.3, not 2.3.x 00045 00046 #include "opencv/cv.h" 00047 #include "opencv2/core/core.hpp" 00048 00049 #include "../common/sharedStructures.h" 00050 #include "../common/color.h" 00051 00052 #include "readWriteLock.h" 00053 00054 00055 00056 namespace cv 00057 { 00058 template<> inline ito::float32 saturate_cast<ito::float32>( ito::float64 v) 00059 { 00060 //return (float32)v; 00061 if(cvIsInf(v)) return std::numeric_limits<ito::float32>::infinity(); 00062 if(cvIsNaN(v)) return std::numeric_limits<ito::float32>::quiet_NaN(); 00063 return static_cast<ito::float32>(std::max ( (ito::float64)(- std::numeric_limits<ito::float32>::max()) , std::min ( v , (ito::float64) std::numeric_limits<ito::float32>::max() ))); 00064 } 00065 00066 template<> inline ito::float64 saturate_cast<ito::float64>( ito::float32 v) 00067 { 00068 //return (float64)v; 00069 if(cvIsInf(v)) return std::numeric_limits<ito::float64>::infinity(); 00070 if(cvIsNaN(v)) return std::numeric_limits<ito::float64>::quiet_NaN(); 00071 return static_cast<ito::float64>(v); 00072 } 00073 00074 template<typename _Tp> static inline _Tp saturate_cast(ito::complex128 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00075 template<typename _Tp> static inline _Tp saturate_cast(ito::complex64 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00076 00077 template<typename _Tp> static inline _Tp saturate_cast(ito::Rgba32 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00078 // template<typename _Tp> static inline ito::Rgba32 saturate_cast(_Tp /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Not defined for input parameter type", "", __FILE__, __LINE__)); return 0; } 00079 00080 template<> inline ito::complex64 saturate_cast(ito::uint8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00081 template<> inline ito::complex64 saturate_cast(ito::int8 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00082 template<> inline ito::complex64 saturate_cast(ito::uint16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00083 template<> inline ito::complex64 saturate_cast(ito::int16 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00084 template<> inline ito::complex64 saturate_cast(ito::uint32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00085 template<> inline ito::complex64 saturate_cast(ito::int32 v){ return ito::complex64(static_cast<ito::float32>(v),0.0); } 00086 template<> inline ito::complex64 saturate_cast(ito::float32 v){ return ito::complex64(v,0.0); } 00087 template<> inline ito::complex64 saturate_cast(ito::float64 v){ return ito::complex64(saturate_cast<ito::float32>(v),0.0); } 00088 template<> inline ito::complex64 saturate_cast(ito::complex64 v){ return v; } 00089 template<> inline ito::complex64 saturate_cast(ito::complex128 v){ return std::complex<ito::float32>(saturate_cast<ito::float32>(v.real()),saturate_cast<ito::float32>(v.imag())); } 00090 00091 template<> inline ito::complex128 saturate_cast(ito::uint8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00092 template<> inline ito::complex128 saturate_cast(ito::int8 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00093 template<> inline ito::complex128 saturate_cast(ito::uint16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00094 template<> inline ito::complex128 saturate_cast(ito::int16 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00095 template<> inline ito::complex128 saturate_cast(ito::uint32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00096 template<> inline ito::complex128 saturate_cast(ito::int32 v){ return ito::complex128(static_cast<ito::float64>(v),0.0); } 00097 template<> inline ito::complex128 saturate_cast(ito::float32 v){ return ito::complex128(saturate_cast<ito::float64>(v),0.0); } 00098 template<> inline ito::complex128 saturate_cast(ito::float64 v){ return ito::complex128(v,0.0); } 00099 template<> inline ito::complex128 saturate_cast(ito::complex64 v){ return ito::complex128(saturate_cast<ito::float64>(v.real()),saturate_cast<ito::float64>(v.imag())); } 00100 template<> inline ito::complex128 saturate_cast(ito::complex128 v){ return v; } 00101 00102 // template<> inline ito::Rgba32 saturate_cast(ito::int8 v) {return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00103 template<> inline ito::Rgba32 saturate_cast(ito::uint8 v) {return ito::Rgba32(v);} 00104 template<> inline ito::Rgba32 saturate_cast(ito::uint16 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00105 // template<> inline ito::Rgba32 saturate_cast(ito::int16 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00106 template<> inline ito::Rgba32 saturate_cast(ito::uint32 v) 00107 { 00108 return ito::Rgba32::fromUnsignedLong(v); 00109 } 00110 template<> inline ito::Rgba32 saturate_cast(ito::int32 v) 00111 { 00112 ito::Rgba32 temp; 00113 temp.rgba = static_cast<ito::uint32>(v); 00114 return temp; 00115 } 00116 template<> inline ito::Rgba32 saturate_cast(ito::float32 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00117 template<> inline ito::Rgba32 saturate_cast(ito::float64 v){return ito::Rgba32(saturate_cast<ito::uint8>(v));} 00118 template<> inline ito::Rgba32 saturate_cast(ito::Rgba32 v){return v;} 00119 00120 template<> inline ito::Rgba32 saturate_cast(ito::int8 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from int8 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00121 template<> inline ito::Rgba32 saturate_cast(ito::int16 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from int16 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00122 template<> inline ito::Rgba32 saturate_cast(ito::complex128 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from complex128 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00123 template<> inline ito::Rgba32 saturate_cast(ito::complex64 /*v*/) { cv::error(cv::Exception(CV_StsAssert, "Cast from complex64 to rgba32 not defined.", "", __FILE__, __LINE__)); return ito::Rgba32(); } 00124 00125 template<> inline ito::uint8 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::uint8>(v.gray());}; 00126 //template<> inline ito::int16 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::int16>(v.gray());}; 00127 template<> inline ito::uint16 saturate_cast(ito::Rgba32 v){return saturate_cast<ito::uint16>(v.gray());}; 00128 template<> inline ito::uint32 saturate_cast(ito::Rgba32 v){return v.argb();}; 00129 template<> inline ito::int32 saturate_cast(ito::Rgba32 v){return (ito::int32)(v.argb());}; 00130 template<> inline ito::float32 saturate_cast(ito::Rgba32 v){return v.gray();}; 00131 template<> inline ito::float64 saturate_cast(ito::Rgba32 v){return (ito::float64)v.gray();}; 00132 00133 00134 template<> class DataType<ito::Rgba32> 00135 { 00136 public: 00137 typedef ito::Rgba32 value_type; 00138 typedef ito::uint8 channel_type; 00139 typedef Vec<channel_type, 4> work_type; 00140 typedef value_type vec_type; 00141 enum 00142 { 00143 generic_type = 0, 00144 depth = cv::DataDepth<channel_type>::value, 00145 channels = 4, 00146 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00147 type = CV_MAKETYPE(depth, channels) 00148 }; 00149 }; 00150 00151 template<> class DataType<ito::RedChannel> 00152 { 00153 public: 00154 typedef ito::RedChannel value_type; 00155 typedef ito::uint8 channel_type; 00156 typedef Vec<channel_type, 4> work_type; 00157 typedef value_type vec_type; 00158 enum 00159 { 00160 generic_type = 0, 00161 depth = cv::DataDepth<channel_type>::value, 00162 channels = 4, 00163 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00164 type = CV_MAKETYPE(depth, channels) 00165 }; 00166 }; 00167 00168 template<> class DataType<ito::GreenChannel> 00169 { 00170 public: 00171 typedef ito::GreenChannel value_type; 00172 typedef ito::uint8 channel_type; 00173 typedef Vec<channel_type, 4> work_type; 00174 typedef value_type vec_type; 00175 enum 00176 { 00177 generic_type = 0, 00178 depth = cv::DataDepth<channel_type>::value, 00179 channels = 4, 00180 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00181 type = CV_MAKETYPE(depth, channels) 00182 }; 00183 }; 00184 00185 template<> class DataType<ito::BlueChannel> 00186 { 00187 public: 00188 typedef ito::BlueChannel value_type; 00189 typedef ito::uint8 channel_type; 00190 typedef Vec<channel_type, 4> work_type; 00191 typedef value_type vec_type; 00192 enum 00193 { 00194 generic_type = 0, 00195 depth = cv::DataDepth<channel_type>::value, 00196 channels = 4, 00197 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00198 type = CV_MAKETYPE(depth, channels) 00199 }; 00200 }; 00201 00202 template<> class DataType<ito::AlphaChannel> 00203 { 00204 public: 00205 typedef ito::AlphaChannel value_type; 00206 typedef ito::uint8 channel_type; 00207 typedef Vec<channel_type, 4> work_type; 00208 typedef value_type vec_type; 00209 enum 00210 { 00211 generic_type = 0, 00212 depth = cv::DataDepth<channel_type>::value, 00213 channels = 4, 00214 fmt = ((channels-1)<<8) + cv::DataDepth<channel_type>::fmt, 00215 type = CV_MAKETYPE(depth, channels) 00216 }; 00217 }; 00218 00219 00220 } // namespace cv 00221 00222 namespace ito { 00223 00224 #define __ITODEBUG 1 00225 00226 class DObjIterator; // Forward declaration 00227 class DataObject; 00228 class Range; 00229 struct Scalar; 00230 class DataObjectTags; 00231 class DataObjectTagType; 00232 class DataObjectTagsPrivate; 00233 00234 00236 00244 template<typename _Tp> static inline ito::tDataType getDataType(const _Tp* /*src*/) 00245 { 00246 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 00247 return ito::tInt8; 00248 } 00249 00250 template<> inline ito::tDataType getDataType(const uint8* /*src*/) { return ito::tUInt8; } 00251 template<> inline ito::tDataType getDataType(const int8* /*src*/) { return ito::tInt8; } 00252 template<> inline ito::tDataType getDataType(const uint16* /*src*/) { return ito::tUInt16; } 00253 template<> inline ito::tDataType getDataType(const int16* /*src*/) { return ito::tInt16; } 00254 template<> inline ito::tDataType getDataType(const uint32* /*src*/) { return ito::tUInt32; } 00255 template<> inline ito::tDataType getDataType(const int32* /*src*/) { return ito::tInt32; } 00256 template<> inline ito::tDataType getDataType(const float32* /*src*/) { return ito::tFloat32; } 00257 template<> inline ito::tDataType getDataType(const float64* /*src*/) { return ito::tFloat64; } 00258 template<> inline ito::tDataType getDataType(const complex64* /*src*/) { return ito::tComplex64; } 00259 template<> inline ito::tDataType getDataType(const complex128* /*src*/) { return ito::tComplex128; } 00260 template<> inline ito::tDataType getDataType(const Rgba32* /*src*/) { return ito::tRGBA32; } 00261 00262 //---------------------------------------------------------------------------------------------------------------------------------- 00267 class DATAOBJ_EXPORT Range 00268 { 00269 public: 00270 Range() : start(0), end(0) {} 00271 Range(int _start, int _end) { _start < _end ? (end = _end, start = _start) : (start = _end, end = _start); } 00272 inline unsigned int size() const { return end - start; } 00273 inline bool empty() const { return (start == end); } 00274 static Range all() { return Range(INT_MIN, INT_MAX); } 00276 int start; 00277 int end; 00278 }; 00279 00280 //---------------------------------------------------------------------------------------------------------------------------------- 00281 class DATAOBJ_EXPORT DataObjectTagType 00282 { 00283 public: 00284 enum tTagType 00285 { 00286 typeInvalid = 0x000000, 00287 typeDouble = 0x000008, 00288 typeString = 0x000020 00289 }; 00290 00291 private: 00292 double m_dVal; 00293 tTagType m_type; 00294 ByteArray m_strValue; 00295 00296 public: 00298 DataObjectTagType() : m_dVal(0), m_strValue(""), m_type(DataObjectTagType::typeInvalid){}; 00299 DataObjectTagType(double dVal) : m_dVal(dVal), m_strValue(""), m_type(DataObjectTagType::typeDouble){}; 00300 DataObjectTagType(const std::string &str) : m_dVal(std::numeric_limits<double>::quiet_NaN()), m_type(DataObjectTagType::typeString){ m_strValue = str.data(); }; 00301 DataObjectTagType(const ByteArray &str) : m_dVal(std::numeric_limits<double>::quiet_NaN()), m_type(DataObjectTagType::typeString){ m_strValue = str; }; 00302 DataObjectTagType(const char* cVal) : m_dVal(std::numeric_limits<double>::quiet_NaN()), m_type(DataObjectTagType::typeString){ cVal == NULL ? m_strValue = "" : m_strValue = cVal;}; 00304 DataObjectTagType(const DataObjectTagType& a) : m_dVal(a.m_dVal), m_type(a.m_type), m_strValue(a.m_strValue) {}; 00305 00306 DataObjectTagType & operator = (const DataObjectTagType &rhs) 00307 { 00308 this->m_dVal = rhs.m_dVal; 00309 this->m_strValue = rhs.m_strValue; 00310 this->m_type = rhs.m_type; 00311 00312 return *this; 00313 } 00314 00315 inline int getType(void) const {return m_type;}; 00316 00317 inline bool isValid(void) const { return (m_type == DataObjectTagType::typeInvalid) ? false: true;}; 00318 00324 inline double getVal_ToDouble(void) 00325 { 00326 if(m_type == DataObjectTagType::typeInvalid) 00327 { 00328 return std::numeric_limits<double>::quiet_NaN(); 00329 } 00330 else if(m_type == DataObjectTagType::typeDouble) 00331 { 00332 return m_dVal; 00333 } 00334 else 00335 { 00336 double dVal = std::numeric_limits<double>::quiet_NaN(); 00337 //dVal = atof(m_strValue.c_str()); //sometimes the result of that line has been arbitrary, therefore this conversion should fail. 00338 return dVal; 00339 } 00340 } 00341 00347 inline ByteArray getVal_ToString(void) 00348 { 00349 if(m_type == DataObjectTagType::typeInvalid) 00350 { 00351 return ""; 00352 } 00353 else if(m_type == DataObjectTagType::typeString) 00354 { 00355 return m_strValue; 00356 } 00357 else 00358 { 00359 if (cvIsNaN(m_dVal)) return "NaN"; 00360 if (cvIsInf(m_dVal)) return "Inf"; 00361 /*if(m_dVal == std::numeric_limits<double>::quiet_NaN()) return std::string("NaN"); 00362 if(m_dVal == std::numeric_limits<double>::signaling_NaN()) return std::string("NaN"); 00363 if(m_dVal == std::numeric_limits<double>::infinity()) return std::string("Inf");*/ 00364 00365 std::ostringstream strs; 00366 strs << m_dVal; 00367 ByteArray ba(strs.str().data()); 00368 00369 return ba; 00370 } 00371 } 00372 }; 00373 00374 //---------------------------------------------------------------------------------------------------------------------------------- 00383 //class DATAOBJ_EXPORT DataObjectTags 00384 //{ 00385 //private: 00386 // DataObjectTagsPrivate *d; 00387 // 00388 // friend class DataObject; 00389 // 00390 // 00391 //public: 00392 // //!< Constructor 00393 // DataObjectTags(unsigned int totalAxisNum); 00394 // 00395 // //!< Destructor 00396 // ~DataObjectTags(); 00397 // 00398 // //!< Copy constructor 00399 // DataObjectTags(const DataObjectTags& copyConstr); 00400 //}; 00401 00402 //---------------------------------------------------------------------------------------------------------------------------------- 00403 00404 class DATAOBJ_EXPORT DObjConstIterator 00405 { 00406 public: 00407 00409 DObjConstIterator(); 00411 DObjConstIterator(const DataObject* _dObj, int pos = 0); 00413 DObjConstIterator(const DObjConstIterator& it); 00414 00416 DObjConstIterator& operator = (const DObjConstIterator& it); 00418 uchar* operator *() const; 00420 uchar* operator [](int i) const; 00421 00423 DObjConstIterator& operator += (int ofs); 00425 DObjConstIterator& operator -= (int ofs); 00427 DObjConstIterator& operator --(); 00429 DObjConstIterator operator --(int); 00431 DObjConstIterator& operator ++(); 00433 DObjConstIterator operator ++(int); 00434 00435 bool operator == (const DObjConstIterator& dObjIt); 00436 bool operator != (const DObjConstIterator& dObjIt); 00437 bool operator < (const DObjConstIterator& dObjIt); 00438 bool operator > (const DObjConstIterator& dObjIt); 00439 bool operator <= (const DObjConstIterator& dObjIt); 00440 bool operator >= (const DObjConstIterator& dObjIt); 00441 00442 protected: 00443 void seekAbs(int ofs); 00444 void seekRel(int ofs); 00445 00446 const DataObject* dObj; 00447 bool planeContinuous; 00448 int elemSize; 00449 uchar* ptr; 00450 uchar* sliceStart; 00451 uchar* sliceEnd; 00452 int plane; 00453 }; 00454 00455 //---------------------------------------------------------------------------------------------------------------------------------- 00456 class DATAOBJ_EXPORT DObjIterator : public DObjConstIterator 00457 { 00458 public: 00459 00461 DObjIterator(); 00463 DObjIterator(DataObject* _dObj, int pos = 0); 00465 DObjIterator(const DObjIterator& it); 00466 00468 DObjIterator& operator = (const DObjIterator& it); 00470 uchar* operator *(); 00472 uchar* operator [](int i); 00473 00475 DObjIterator& operator += (int ofs); 00477 DObjIterator& operator -= (int ofs); 00479 DObjIterator& operator --(); 00481 DObjIterator operator --(int); 00483 DObjIterator& operator ++(); 00485 DObjIterator operator ++(int); 00486 }; 00487 00488 //---------------------------------------------------------------------------------------------------------------------------------- 00489 class DATAOBJ_EXPORT DataObject 00490 { 00491 private: 00492 00494 00508 //length(sizes) == length(steps) 00509 void createHeader(const unsigned char dimensions, const int *sizes, const int *steps, const int elemSize) 00510 { 00511 if(dimensions == 1) 00512 { 00513 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__)); 00514 } 00515 00516 m_dims = dimensions; 00517 00518 if(dimensions > 0) 00519 { 00520 if (m_roi.m_p) 00521 { 00522 if (*(m_roi.m_p-1) != dimensions) 00523 { 00524 delete[] (m_roi.m_p - 1); 00525 00526 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00527 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00528 m_osize.m_p[-1] = dimensions; 00529 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00530 m_size.m_p[-1] = dimensions; 00531 m_roi.m_p = m_roi.m_p + 1; 00532 m_roi.m_p[-1] = dimensions; 00533 } 00534 } 00535 else 00536 { 00537 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00538 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00539 m_osize.m_p[-1] = dimensions; 00540 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00541 m_size.m_p[-1] = dimensions; 00542 m_roi.m_p = m_roi.m_p + 1; 00543 m_roi.m_p[-1] = dimensions; 00544 } 00545 00546 for (uchar n = 0 ; n < dimensions ; n++) 00547 { 00548 m_size.m_p[n] = sizes[n]; 00549 m_roi.m_p[n] = 0; 00550 00551 if(steps == NULL || n == 0) 00552 { 00553 m_osize.m_p[n] = sizes[n]; 00554 } 00555 else if(n == dimensions - 1) //last element 00556 { 00557 if (elemSize == 0) 00558 cv::Exception(CV_StsAssert, "elemSize is zero", "", __FILE__, __LINE__); 00559 m_osize.m_p[n] = steps[n-1] / elemSize; 00560 } 00561 else /*if(n < dimensions -1)*/ 00562 { 00563 if (steps[n] == 0) 00564 cv::Exception(CV_StsAssert, "step size is zero", "", __FILE__, __LINE__); 00565 m_osize.m_p[n] = steps[n - 1] / steps[n]; 00566 } 00567 } 00568 } 00569 } 00570 00572 00585 void createHeaderWithROI(const unsigned char dimensions, const int *sizes, const int *osizes = NULL, const int *roi = NULL) 00586 { 00587 if(dimensions == 1) 00588 { 00589 cv::error(cv::Exception(CV_StsAssert, "number of dimensions must be at least 2", "", __FILE__, __LINE__)); 00590 } 00591 00592 m_dims = dimensions; 00593 00594 if(dimensions > 0) 00595 { 00596 00597 if (m_roi.m_p) 00598 { 00599 if (*(m_roi.m_p-1) != dimensions) 00600 { 00601 delete[] (m_roi.m_p-1); 00602 00603 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00604 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00605 m_osize.m_p[-1] = dimensions; 00606 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00607 m_size.m_p[-1] = dimensions; 00608 m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one 00609 m_roi.m_p[-1] = dimensions; 00610 } 00611 } 00612 else 00613 { 00614 m_roi.m_p = new int [(dimensions + 1) + (dimensions + 1) + (dimensions + 1)]; 00615 m_osize.m_p = static_cast<int *>(m_roi.m_p + dimensions) + 1; 00616 m_osize.m_p[-1] = dimensions; 00617 m_size.m_p = static_cast<int *>(m_osize.m_p + dimensions) + 1; 00618 m_size.m_p[-1] = dimensions; 00619 m_roi.m_p = m_roi.m_p + 1; //move m_p pointer by one 00620 m_roi.m_p[-1] = dimensions; 00621 } 00622 00623 for (uchar n = 0; n < dimensions; n++) 00624 { 00625 m_size.m_p[n] = sizes[n]; 00626 00627 if (osizes) 00628 { 00629 m_osize.m_p[n] = osizes[n]; 00630 } 00631 else 00632 { 00633 m_osize.m_p[n] = sizes[n]; 00634 } 00635 00636 if (roi) 00637 { 00638 m_roi.m_p[n] = roi[n]; 00639 } 00640 else 00641 { 00642 m_roi.m_p[n] = 0; 00643 } 00644 } 00645 } 00646 } 00647 00648 void create(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous, const uchar* continuousDataPtr = NULL, const int* steps = NULL); 00649 void create(const unsigned char dimensions, const int *sizes, const int type, const cv::Mat* planes, const unsigned int nrOfPlanes); 00650 00651 void freeData(void); 00652 void secureFreeData(void); 00655 //---------------------------------------------------------------------------------------------------------------------------------- 00656 ito::RetVal matNumToIdx(const int matNum, int *matIdx) const; 00657 00659 00667 inline ito::RetVal matIdxToNum(const unsigned int *matIdx, int *matNum) const 00668 { 00669 *matNum = 0; 00670 if (m_dims <= 2) 00671 { 00672 return 0; 00673 } 00674 00675 int planeSize = 1; 00676 00677 for (int n = m_dims - 3; n >= 0; n--) 00678 { 00679 #if __ITODEBUG 00680 if (((int)matIdx[n] + m_roi[n]) >= m_osize[n]) 00681 { 00682 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__, __LINE__)); 00683 } 00684 #endif 00685 (*matNum) += ((int)matIdx[n] + m_roi[n]) * planeSize; //CAST_TODO 00686 planeSize *= m_osize[n]; 00687 } 00688 00689 return 0; 00690 } 00691 00692 struct DATAOBJ_EXPORT MSize 00693 { 00694 inline MSize() : m_p(NULL) {} 00695 inline int operator [] (const int dim) const 00696 { 00697 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory 00698 }; 00699 inline operator const int * () const { return m_p; } 00700 bool operator == (const MSize& sz) const 00701 { 00702 if(m_p == NULL || sz.m_p == NULL) 00703 { 00704 return sz.m_p == m_p; 00705 } 00706 00707 int d = m_p[-1], dsz = sz.m_p[-1]; 00708 if( d != dsz ) 00709 return false; 00710 if( d == 2 ) 00711 { 00712 return m_p[0] == sz.m_p[0] && m_p[1] == sz.m_p[1]; 00713 } 00714 00715 for( int i = 0; i < d - 2; i++ ) 00716 { 00717 if( m_p[i] != sz.m_p[i] ) 00718 { 00719 return false; 00720 } 00721 } 00722 return (m_p[d - 2] == sz.m_p[d - 2]) && (m_p[d - 1] == sz.m_p[d - 1]); 00723 } 00724 00725 inline bool operator != (const MSize& sz) const { return !(*this == sz); } 00726 00727 int *m_p; 00728 }; 00729 00730 struct DATAOBJ_EXPORT MROI 00731 { 00732 inline MROI() : m_p(NULL) {}; 00733 inline int operator [] (const int dim) const 00734 { 00735 return m_p[dim]; //return the size value. this operator corresponds to the real data representation in memory 00736 } 00737 00738 bool operator == (const MROI & rroi) const 00739 { 00740 if(m_p == NULL || rroi.m_p == NULL) 00741 { 00742 return rroi.m_p == m_p; 00743 } 00744 00745 if (m_p[-1] != rroi.m_p[-1]) 00746 { 00747 return false; 00748 } 00749 00750 int d = m_p[-1]; 00751 for (int n = 0; n < d - 2; n++) 00752 { 00753 if (m_p[n] != rroi.m_p[n]) 00754 { 00755 return false; 00756 } 00757 } 00758 00759 return m_p[d - 2] == rroi.m_p[d - 2] && m_p[d - 1] == rroi.m_p[d - 1]; 00760 00761 } 00762 00763 int *m_p; 00764 }; 00765 00766 DataObject(const DataObject& dObj, bool transposed); 00768 char m_continuous; 00769 char m_owndata; 00770 int m_type; 00771 int *m_pRefCount; 00772 int m_dims; 00773 MSize m_osize; 00774 MROI m_roi; 00775 MSize m_size; 00776 uchar **m_data; 00777 ReadWriteLock *m_objSharedDataLock; 00778 DataObjectTagsPrivate *m_pDataObjectTags; 00779 ReadWriteLock m_objHeaderLock; 00780 static const int m_sizeofs; 00781 00782 int mdata_realloc(const int size); 00783 00784 int mdata_size(void) const; 00785 00786 int mdata_free(); 00787 00788 RetVal copyFromData2DInternal(const uchar* src, const int sizeOfElem, const int sizeX, const int sizeY); 00789 RetVal copyFromData2DInternal(const uchar* src, const int sizeOfElem, const int sizeX, const int x0, const int y0, const int width, const int height); 00790 00791 00792 //low-level, templated methods 00793 //most low-level methods are marked "friend" such that they can access private members of their data object parameters 00794 template<typename _Tp> friend RetVal CreateFunc(DataObject *dObj, const unsigned char dimensions, const int *sizes, const unsigned char continuous, const uchar* continuousDataPtr, const int* steps); 00795 template<typename _Tp> friend RetVal CreateFuncWithCVPlanes(DataObject *dObj, const unsigned char dimensions, const int *sizes, const cv::Mat* planes, const unsigned int nrOfPlanes); 00796 template<typename _Tp> friend RetVal FreeFunc(DataObject *dObj); 00797 template<typename _Tp> friend RetVal SecureFreeFunc(DataObject *dObj); 00798 template<typename _Tp> friend RetVal CopyToFunc(const DataObject &lhs, DataObject &rhs, unsigned char regionOnly); 00799 template<typename _Tp> friend RetVal ConvertToFunc(const DataObject &lhs, DataObject &rhs, const int type, const double alpha, const double beta); 00800 template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, const int *lims); 00801 template<typename _Tp> friend RetVal MinMaxLocFunc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos, int *maxPos); 00802 template<typename _Tp> friend RetVal AssignScalarFunc(const DataObject *src, const ito::tDataType type, const void *scalar); 00803 template<typename _Tp> friend RetVal MakeContinuousFunc(const DataObject &dObj, DataObject &resDObj); 00804 template<typename _Tp> friend RetVal EvaluateTransposeFlagFunc(DataObject *dObj); 00805 template<typename _Tp> friend RetVal CalcMinMaxValues(DataObject *lhs, double &result_min, double &result_max, const int cmplxSel = 0); 00806 template<typename _Tp> friend std::ostream& coutFunc(std::ostream& out, const DataObject& dObj); 00807 00808 // more friends due to change of std::vector to int ** for m_data ... 00809 template<typename _Tp> friend RetVal GetRangeFunc(DataObject *dObj, const int dtop, const int dbottom, const int dleft, const int dright); 00810 template<typename _Tp> friend RetVal AdjustROIFunc(DataObject *dObj, int dtop, int dbottom, int dleft, int dright); 00811 00812 public: 00813 int seekMat(const int matNum, const int numMats) const; 00814 int seekMat(const int matNum) const; 00815 int calcNumMats(void) const; 00816 00817 // TAGSPACEFUNCTIONS 00818 00820 double getValueOffset() const; 00821 00823 double getValueScale() const; 00824 00826 const std::string getValueUnit() const; 00827 00829 std::string getValueDescription() const; 00830 00832 double getAxisOffset(const int axisNum) const; 00833 00835 double getAxisScale(const int axisNum) const; 00836 00838 const std::string getAxisUnit(const int axisNum, bool &validOperation) const; 00839 00841 std::string getAxisDescription(const int axisNum, bool &validOperation) const; 00842 00843 DataObjectTagType getTag(const std::string &key, bool &validOperation) const; 00844 00845 bool getTagByIndex(const int tagNumber, std::string &key, DataObjectTagType &value) const; 00846 00848 std::string getTagKey(const int tagNumber, bool &validOperation) const; 00849 00851 int getTagListSize() const; 00852 00854 int setValueUnit(const std::string &unit); 00855 00857 int setValueDescription(const std::string &description); 00858 00859 //inline lead to a linker error on MSVC when calling from several methods 00860 int setAxisOffset(const unsigned int axisNum, const double offset); 00861 int setAxisScale(const unsigned int axisNum, const double scale); 00862 int setAxisUnit(const unsigned int axisNum, const std::string &unit); //unit must be latin1 encoded 00863 int setAxisDescription(const unsigned int axisNum, const std::string &description); //description must be latin1 encoded 00864 int setTag(const std::string &key, const DataObjectTagType &value); 00865 bool existTag(const std::string &key) const; 00866 bool deleteTag(const std::string &key); 00867 bool deleteAllTags(); 00868 int addToProtocol(const std::string &value); 00869 00870 00881 inline double getPhysToPix(const unsigned int dim, const double phys, bool &isInsideImage) const 00882 { 00883 double tPx = 0.0; 00884 if(static_cast<int>(dim) >= m_dims) 00885 { 00886 if(phys == 0.0) 00887 { 00888 isInsideImage = true; 00889 } 00890 else 00891 { 00892 isInsideImage = false; 00893 } 00894 return 0.0; 00895 } 00896 00897 if(m_pDataObjectTags) 00898 { 00899 tPx = (phys / getAxisScale(dim) + getAxisOffset(dim)); 00900 } 00901 else 00902 { 00903 tPx = phys; 00904 } 00905 00906 if(tPx > getSize(dim) - 1) 00907 { 00908 isInsideImage = false; 00909 tPx = static_cast<double>(getSize(dim)- 1); 00910 } 00911 else if( tPx < 0) 00912 { 00913 isInsideImage = false; 00914 tPx = 0; 00915 } 00916 else 00917 { 00918 isInsideImage = true; 00919 } 00920 00921 return tPx; 00922 } 00923 00927 inline int getPhysToPix2D(const double physY, double &tPxY, bool &isInsideImageY, const double physX, double &tPxX, bool &isInsideImageX) const 00928 { 00929 if(m_dims < 2) 00930 { 00931 tPxY = physY; 00932 if(physY != 0.0) 00933 { 00934 isInsideImageY = false; 00935 } 00936 00937 tPxX = physX / getAxisScale(0) + getAxisOffset(0); //m_pDataObjectTags->m_axisScales[0] + m_pDataObjectTags->m_axisOffsets[0]; 00938 00939 if(tPxX > m_size[0] - 1) 00940 { 00941 isInsideImageX = false; 00942 tPxX = static_cast<double>(m_size[0] - 1); 00943 } 00944 } 00945 else 00946 { 00947 if(m_pDataObjectTags) 00948 { 00949 tPxX = physX / getAxisScale(m_dims - 1) + getAxisOffset(m_dims - 1); 00950 tPxY = physY / getAxisScale(m_dims - 2) + getAxisOffset(m_dims - 2); 00951 } 00952 else 00953 { 00954 tPxX = physX; 00955 tPxY = physY; 00956 } 00957 00958 if(tPxY > m_size[m_dims - 2] - 1) 00959 { 00960 isInsideImageY = false; 00961 tPxY = static_cast<double>(m_size[m_dims - 2] - 1); 00962 } 00963 if(tPxX > m_size[m_dims - 1] - 1) 00964 { 00965 isInsideImageX = false; 00966 tPxY = static_cast<double>(m_size[m_dims - 1] - 1); 00967 } 00968 } 00969 00970 if(tPxX < 0) 00971 { 00972 tPxX = 0; 00973 isInsideImageX = false; 00974 } 00975 if(tPxY < 0) 00976 { 00977 tPxY = 0; 00978 isInsideImageY = false; 00979 } 00980 return 0; 00981 } 00982 00992 inline double getPixToPhys(const unsigned int dim, const double pix, bool &isInsideImage) const 00993 { 00994 double tPhys = 0.0; 00995 if(static_cast<int>(dim) >= m_dims) 00996 { 00997 if(pix == 0) 00998 { 00999 isInsideImage = true; 01000 } 01001 else 01002 { 01003 isInsideImage = false; 01004 } 01005 return 0.0; 01006 } 01007 if(m_pDataObjectTags) 01008 { 01009 tPhys = (pix - getAxisOffset(dim)) * getAxisScale(dim); 01010 } 01011 else 01012 { 01013 tPhys = pix; 01014 } 01015 01016 if((pix > getSize(dim) - 1) || (pix < 0)) 01017 { 01018 isInsideImage = false; 01019 } 01020 else 01021 { 01022 isInsideImage = true; 01023 } 01024 01025 return tPhys; 01026 } 01027 01041 RetVal setXYRotationalMatrix(double r11, double r12, double r13, double r21, double r22, double r23, double r31, double r32, double r33); 01042 01056 RetVal getXYRotationalMatrix(double &r11, double &r12, double &r13, double &r21, double &r22, double &r23, double &r31, double &r32, double &r33) const; 01057 01058 RetVal copyTagMapTo(DataObject &rhs) const; 01059 RetVal copyAxisTagsTo(DataObject &rhs) const; 01061 // END TAGSPACE 01062 01064 inline int getDims(void) const { return m_dims; } 01065 01067 inline int getType(void) const { return m_type; } 01068 01070 inline char getContinuous(void) const { return m_continuous; } 01071 01073 inline char getOwnData(void) const { return m_owndata; } 01074 01076 01080 inline int getTotal() const 01081 { 01082 int dims = getDims(); 01083 int total = dims > 0 ? 1 : 0; 01084 for(int i = 0 ; i<dims ; i++) 01085 { 01086 total *= getSize(i); 01087 } 01088 return total; 01089 01090 } 01091 01093 01097 inline int getOriginalTotal() const 01098 { 01099 int dims = getDims(); 01100 int total = dims > 0 ? 1 : 0; 01101 for(int i = 0 ; i<dims ; i++) 01102 { 01103 total *= m_osize[i]; 01104 } 01105 return total; 01106 01107 } 01108 01110 01118 inline void lockRead() 01119 { 01120 m_objHeaderLock.lockRead(); 01121 if(m_objSharedDataLock) m_objSharedDataLock->lockRead(); 01122 } 01123 01125 01128 inline void lockWrite() 01129 { 01130 m_objHeaderLock.lockWrite(); 01131 if(m_objSharedDataLock) m_objSharedDataLock->lockWrite(); 01132 } 01133 01135 01138 inline void unlock() 01139 { 01140 if(m_objSharedDataLock) m_objSharedDataLock->unlock(); 01141 m_objHeaderLock.unlock(); 01142 } 01143 01144 RetVal copyTo(DataObject &rhs, unsigned char regionOnly = 0); 01145 RetVal convertTo(DataObject &rhs, const int type, const double alpha=1, const double beta=0 ) const; 01146 RetVal deepCopyPartial(DataObject &rhs); 01148 uchar ** get_mdata(void); 01149 uchar ** get_mdata(void) const; 01150 01151 cv::Mat* getCvPlaneMat(const int planeIndex); 01152 const cv::Mat* getCvPlaneMat(const int planeIndex) const; 01153 01155 01158 inline MSize getSize(void) { return m_size; } 01159 01161 01164 inline const MSize getSize(void) const { return m_size; } 01165 01167 01171 int getSize(int index) const 01172 { 01173 if(index < 0 || index >= m_dims) 01174 { 01175 return -1; 01176 } 01177 else 01178 { 01179 return m_size[index]; 01180 } 01181 } 01182 01184 01188 int getOriginalSize(int index) const 01189 { 01190 if(index < 0 || index >= m_dims) 01191 { 01192 return -1; 01193 } 01194 else 01195 { 01196 return m_osize[index]; 01197 } 01198 } 01199 01201 DObjIterator begin(); 01203 DObjIterator end(); 01204 01205 DObjConstIterator constBegin() const; 01206 DObjConstIterator constEnd() const; 01207 01209 01212 DataObject(void) : m_continuous(1), m_owndata(1), m_type(0), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) {} 01213 01215 01223 DataObject(const int size, const int type): m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01224 { 01225 int sizes[2] = {1, size}; 01226 this->create(2, sizes, type, 1); 01227 } 01228 01230 01238 DataObject(const int sizeY, const int sizeX, const int type): m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01239 { 01240 int sizes[2] = {sizeY, sizeX}; 01241 this->create(2, sizes, type, 1); 01242 } 01243 01245 01255 DataObject(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0) : m_continuous(continuous), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01256 { 01257 int sizes[3] = {sizeZ, sizeY, sizeX}; 01258 this->create(3, sizes, type, m_continuous); 01259 } 01260 01262 01276 DataObject(const int sizeZ, const int sizeY, const int sizeX, const int type, const uchar* continuousDataPtr, const int* steps = NULL) : m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01277 { 01278 int sizes[3] = {sizeZ, sizeY, sizeX}; 01279 this->create(3, sizes, type, m_continuous, continuousDataPtr, steps); 01280 } 01281 01283 01292 DataObject(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0) : m_continuous(continuous), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01293 { 01294 this->create(dimensions, sizes, type, m_continuous); 01295 } 01296 01298 01311 DataObject(const unsigned char dimensions, const int *sizes, const int type, const uchar* continuousDataPtr, const int* steps = NULL) : m_continuous(1), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01312 { 01313 this->create(dimensions, sizes, type, m_continuous, continuousDataPtr, steps); 01314 } 01315 01316 DataObject(const unsigned char dimensions, const int *sizes, const int type, const cv::Mat* planes, const unsigned int nrOfPlanes) : m_continuous(0), m_owndata(1), m_pRefCount(0), m_dims(0), m_data(NULL), m_objSharedDataLock(0), m_pDataObjectTags(0) 01317 { 01318 //usually it is dangerous to say that m_owndata is 1 in this case, since we cannot be sure if the given planes are the owner of their data. 01319 //however, in this case, owndata is unimportant since the created dataObject is always not continuous, therefore owndata will never 01320 //be analyzed and the destructor of the dataObject never tries to delete the continuous data block. The underlying cv::Mats however still know 01321 //whether they can or can't delete their data. 01322 this->create(dimensions, sizes, type, planes, nrOfPlanes); 01323 } 01324 01325 DataObject(const DataObject& copyConstr); 01327 01328 01334 ~DataObject(void) 01335 { 01336 freeData(); 01337 } 01338 01340 DataObject & operator = (const cv::Mat &rhs); 01341 DataObject & operator = (const DataObject &rhs); 01342 DataObject & operator = (const int8 &value); 01343 DataObject & operator = (const uint8 &value); 01344 DataObject & operator = (const int16 &value); 01345 DataObject & operator = (const uint16 &value); 01346 DataObject & operator = (const int32 &value); 01347 DataObject & operator = (const uint32 &value); 01348 DataObject & operator = (const float32 &value); 01349 DataObject & operator = (const float64 &value); 01350 DataObject & operator = (const complex64 &value); 01351 DataObject & operator = (const complex128 &value); 01352 DataObject & operator = (const ito::Rgba32 &value); 01355 DataObject & operator += (const DataObject &rhs); 01356 DataObject & operator += (const float64 &value); 01357 01358 DataObject operator + (const DataObject &rhs); 01359 DataObject operator + (const float64 &value); 01360 01361 DataObject & operator -= (const DataObject &rhs); 01362 DataObject & operator -= (const float64 &value); 01363 01364 DataObject operator - (const DataObject &rhs); 01365 DataObject operator - (const float64 &value); 01366 01367 DataObject & operator *= (const DataObject &rhs); 01368 DataObject & operator *= (const float64 &factor); 01369 01370 DataObject operator * (const DataObject &rhs); 01371 DataObject operator * (const float64 &factor); 01372 01373 // Comparison Operators 01374 DataObject operator < (DataObject &rhs); 01375 DataObject operator > (DataObject &rhs); 01376 DataObject operator <= (DataObject &rhs); 01377 DataObject operator >= (DataObject &rhs); 01378 DataObject operator == (DataObject &rhs); 01379 DataObject operator != (DataObject &rhs); 01380 01381 01382 // bitshift operators 01383 DataObject operator << (const unsigned int shiftbit); 01384 DataObject & operator <<= (const unsigned int shiftbit); 01385 DataObject operator >> (const unsigned int shiftbit); 01386 DataObject & operator >>= (const unsigned int shiftbit); 01387 01388 // bitwise operators 01389 DataObject operator & (const DataObject & rhs); 01390 DataObject & operator &= (const DataObject & rhs); 01391 DataObject operator | (const DataObject & rhs); 01392 DataObject & operator |= (const DataObject & rhs); 01393 DataObject operator ^ (const DataObject & rhs); 01394 DataObject & operator ^= (const DataObject & rhs); 01395 01396 // allocates matrix with zero values 01397 RetVal zeros(const int type); 01398 RetVal zeros(const int size, const int type); 01399 RetVal zeros(const int sizeY, const int sizeX, const int type); 01400 RetVal zeros(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0); 01401 RetVal zeros(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0); 01402 01403 // allocates matrix with all values set to one 01404 RetVal ones(const int type); 01405 RetVal ones(const int size, const int type); 01406 RetVal ones(const int sizeY, const int sizeX, const int type); 01407 RetVal ones(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0); 01408 RetVal ones(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0); 01409 01410 // allocates matrix with uniform distributed noise 01411 RetVal rand(const int type, const bool randMode = false); 01412 RetVal rand(const int size, const int type, const bool randMode = false); 01413 RetVal rand(const int sizeY, const int sizeX, const int type, const bool randMode = false); 01414 RetVal rand(const int sizeZ, const int sizeY, const int sizeX, const int type, const bool randMode, const unsigned char continuous = 0); 01415 RetVal rand(const unsigned char dimensions, const int *sizes, const int type, const bool randMode, const unsigned char continuous = 0); 01416 01417 // allocates matrix with eye-matrix representation 01418 RetVal eye(const int type); 01419 RetVal eye(const int size, const int type); 01420 01421 RetVal conj(); 01422 DataObject adj() const; 01423 DataObject trans() const; 01424 01425 //RetVal makeContinuous(void); 01426 01427 DataObject mul(const DataObject &mat2, const double scale = 1.0); 01428 DataObject div(const DataObject &mat2, const double scale = 1.0); 01429 DataObject squeeze() const; 01430 int elemSize() const; 01431 01433 01438 template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) const 01439 { 01440 #if __ITODEBUG 01441 if (m_dims != 2) 01442 { 01443 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01444 } 01445 else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) ) 01446 { 01447 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01448 } 01449 #endif 01450 return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x); 01451 } 01452 01454 01459 template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) 01460 { 01461 #if __ITODEBUG 01462 if (m_dims != 2) 01463 { 01464 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01465 } 01466 else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) ) 01467 { 01468 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01469 } 01470 01471 #endif 01472 return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x); 01473 } 01474 01476 01482 template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) const 01483 { 01484 #if __ITODEBUG 01485 if (m_dims != 3) 01486 { 01487 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01488 } 01489 else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0]))) 01490 { 01491 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01492 } 01493 #endif 01494 01495 return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x); 01496 } 01497 01499 01505 template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) 01506 { 01507 #if __ITODEBUG 01508 if (m_dims != 3) 01509 { 01510 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01511 } 01512 else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0]))) 01513 { 01514 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01515 } 01516 #endif 01517 return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x); 01518 } 01519 01521 01526 template<typename _Tp> _Tp& at(const unsigned int *idx) const //idx is in virtual order 01527 { 01528 int matNum = 0; 01529 01530 matIdxToNum(idx, &matNum); 01531 01532 return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]); 01533 } 01534 01536 01541 template<typename _Tp> _Tp& at(const unsigned int *idx) //idx is in virtual order 01542 { 01543 int matNum = 0; 01544 01545 matIdxToNum(idx, &matNum); 01546 01547 return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]); 01548 } 01549 01550 DataObject at(const ito::Range &rowRange, const ito::Range &colRange); 01551 DataObject at(ito::Range *ranges); 01553 01554 01560 uchar* rowPtr(const int matNum, const int y) 01561 { 01562 int matIndex = seekMat(matNum); 01563 return ((cv::Mat*)m_data[matIndex])->ptr(y); 01564 } 01565 01567 01573 const uchar* rowPtr(const int matNum, const int y) const 01574 { 01575 int matIndex = seekMat(matNum); 01576 return ((cv::Mat*)m_data[matIndex])->ptr(y); 01577 } 01578 01579 DataObject row(const int selRow); 01580 DataObject col(const int selCol); 01581 01582 DataObject toGray(const int destinationType = ito::tUInt8); 01583 01584 // ROI 01585 DataObject & adjustROI(const int dtop, const int dbottom, const int dleft, const int dright); 01586 DataObject & adjustROI(const unsigned char dims, const int *lims); 01587 RetVal locateROI(int *wholeSizes, int *offsets); 01588 RetVal locateROI(int *lims); 01590 01591 01606 template<typename _Tp> RetVal copyFromData2D(const _Tp* src, const int sizeX, const int sizeY) { return copyFromData2DInternal((const uchar*)src, sizeof(_Tp), sizeX, sizeY); } // copies 2D continuous data into data object, data object must have correct size and type, otherwise an error is returned 01607 01609 01633 template<typename _Tp> RetVal copyFromData2D(const _Tp *src, const int sizeX, const int sizeY, const int x0, const int y0, const int width, const int height) { return copyFromData2DInternal((const uchar*)src, sizeof(_Tp), sizeX, x0, y0, width, height); } // copies 2D continuous data into data object, data object must have correct size and type, otherwise an error is returned 01634 01635 //---------------------------------------------------------------------------------------------------------------------------------- 01637 /* 01638 \param [in] src is any variable whose type is checked 01639 \return retOk if both types are equal, retError if they are not equal or if the type of src is unknown 01640 */ 01641 template<typename _Tp> RetVal checkType(const _Tp *src) //must be inline since function template! 01642 { 01643 try 01644 { 01645 if(m_type == ito::getDataType(src)) 01646 { 01647 return ito::retOk; 01648 } 01649 return RetVal(retError,0,"CheckType failed: types are not equal"); 01650 } 01651 catch(cv::Exception /*&ex*/) 01652 { 01653 return RetVal(retError,0,"Error during Type-Check. Type not templated"); 01654 } 01655 } 01656 01657 // 01658 template<typename T2> operator T2 (); 01660 template<typename _Tp> RetVal linspace(const _Tp start, const _Tp end, const _Tp inc, const int transposed); 01661 01662 }; 01663 01664 //template<> DATAOBJ_EXPORT RetVal ito::DataObject::linspace<ito::int8>(const ito::int8 /*start*/, const ito::int8 /*end*/, const ito::int8 /*inc*/, const int /*transposed*/); 01665 //template<> DATAOBJ_EXPORT RetVal ito::DataObject::linspace<ito::uint8>(const ito::uint8 /*start*/, const ito::uint8 /*end*/, const ito::uint8 /*inc*/, const int /*transposed*/); 01666 01667 01668 //---------------------------------------------------------------------------------------------------------------------------------- 01669 // functions for DataObject in namespace ITO, which are NOT member functions 01670 //---------------------------------------------------------------------------------------------------------------------------------- 01671 DataObject DATAOBJ_EXPORT abs(const DataObject &dObj); 01672 DataObject DATAOBJ_EXPORT arg(const DataObject &dObj); 01673 DataObject DATAOBJ_EXPORT real(const DataObject &dObj); 01674 DataObject DATAOBJ_EXPORT imag(const DataObject &dObj); 01676 DataObject DATAOBJ_EXPORT makeContinuous(const DataObject &dObj); 01678 template<typename _Tp, typename _T2> RetVal CastFunc(const DataObject *dObj, DataObject *resObj, double alpha = 1.0, double beta = 0.0); 01679 01680 //RetVal minMaxLoc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos = NULL, int *maxPos = NULL); 01681 01683 01690 template<typename _Tp> _Tp numberConversion(ito::tDataType fromType, void *scalar) 01691 { 01692 //_Tp retValue = 0; 01693 _Tp retValue; 01694 01695 switch(fromType) 01696 { 01697 case ito::tUInt8: 01698 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint8*>(scalar))); 01699 break; 01700 case ito::tInt8: 01701 retValue = cv::saturate_cast<_Tp>(*(static_cast<int8*>(scalar))); 01702 break; 01703 case ito::tUInt16: 01704 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint16*>(scalar))); 01705 break; 01706 case ito::tInt16: 01707 retValue = cv::saturate_cast<_Tp>(*(static_cast<int16*>(scalar))); 01708 break; 01709 case ito::tUInt32: 01710 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint32*>(scalar))); 01711 break; 01712 case ito::tInt32: 01713 retValue = cv::saturate_cast<_Tp>(*(static_cast<int32*>(scalar))); 01714 break; 01715 case ito::tFloat32: 01716 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float32*>(scalar))); 01717 break; 01718 case ito::tFloat64: 01719 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float64*>(scalar))); 01720 break; 01721 case ito::tComplex64: 01722 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex64*>(scalar))); 01723 break; 01724 case ito::tComplex128: 01725 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex128*>(scalar))); 01726 break; 01727 case ito::tRGBA32: 01728 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::Rgba32*>(scalar))); 01729 break; 01730 default: 01731 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01732 retValue = 0; 01733 } 01734 01735 return retValue; 01736 }; 01737 01738 //template<> ito::Rgba32 numberConversion<ito::Rgba32>(ito::tDataType fromType, void *scalar) 01739 //{ 01740 // _Tp retValue = 0; 01741 // 01742 // switch(fromType) 01743 // { 01744 // case ito::tUInt8: 01745 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint8*>(scalar))); 01746 // break; 01747 // case ito::tInt8: 01748 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int8*>(scalar))); 01749 // break; 01750 // case ito::tUInt16: 01751 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint16*>(scalar))); 01752 // break; 01753 // case ito::tInt16: 01754 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int16*>(scalar))); 01755 // break; 01756 // case ito::tUInt32: 01757 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint32*>(scalar))); 01758 // break; 01759 // case ito::tInt32: 01760 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int32*>(scalar))); 01761 // break; 01762 // case ito::tFloat32: 01763 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float32*>(scalar))); 01764 // break; 01765 // case ito::tFloat64: 01766 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float64*>(scalar))); 01767 // break; 01768 // case ito::tComplex64: 01769 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex64*>(scalar))); 01770 // break; 01771 // case ito::tComplex128: 01772 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex128*>(scalar))); 01773 // break; 01774 // case ito::tRGBA32: 01775 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::Rgba32*>(scalar))); 01776 // break; 01777 // default: 01778 // cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01779 // retValue = 0; 01780 // } 01781 // 01782 // return retValue; 01783 //} 01784 01785 //---------------------------------------------------------------------------------------------------------------------------------- 01786 // cout 01787 //---------------------------------------------------------------------------------------------------------------------------------- 01788 template<typename _Tp> static std::ostream& coutFunc(std::ostream& out, const DataObject& dObj) 01789 { 01790 //cv::Mat_<_Tp> *cvMat = NULL; 01791 int numMats = dObj.calcNumMats(); 01792 int tMat = 0; 01793 01794 if (dObj.getDims() == 0) 01795 { 01796 std::cout << "DataObject()\n" << std::endl; 01797 } 01798 else 01799 { 01800 std::cout << "DataObject(size=[" << dObj.getSize(0); 01801 for (int dim = 1; dim < dObj.getDims(); ++dim) 01802 { 01803 std::cout << "x" << dObj.getSize(dim); 01804 } 01805 std::cout << "]\n" << std::endl; 01806 01807 int *idx = new int[dObj.getDims()]; 01808 01809 01810 for (int nMat = 0; nMat < numMats; nMat++) 01811 { 01812 tMat = dObj.seekMat(nMat, numMats); 01813 //std::cout << tMat + 1 << "->("; 01814 01815 dObj.matNumToIdx(tMat, idx); 01816 std::cout << "["; 01817 for (int i = 0; i < dObj.getDims() - 2; ++i) 01818 { 01819 std::cout << idx[i] << ","; 01820 } 01821 std::cout << ":,:]->("; 01822 01823 std::cout << cv::format( (*((cv::Mat_<_Tp> *)((dObj.get_mdata())[tMat]))) , "numpy" ) << std::endl << std::endl; 01824 01825 std::cout << ")" << "\n" << std::endl; 01826 } 01827 01828 delete[] idx; 01829 01830 std::cout << ")" << "\n" << std::endl; 01831 } 01832 return out; 01833 01834 } 01835 01836 typedef std::ostream& (*tCoutFunc)(std::ostream& out, const DataObject& dObj); 01837 01838 static tCoutFunc fListCout[] = 01839 { 01840 coutFunc<int8>, 01841 coutFunc<uint8>, 01842 coutFunc<int16>, 01843 coutFunc<uint16>, 01844 coutFunc<int32>, 01845 coutFunc<uint32>, 01846 coutFunc<ito::float32>, 01847 coutFunc<ito::float64>, 01848 coutFunc<ito::complex64>, 01849 coutFunc<ito::complex128>, 01850 coutFunc<ito::Rgba32> 01851 }; 01852 01853 static inline std::ostream& operator << (std::ostream& out, const DataObject& dObj) 01854 { 01855 return fListCout[dObj.getType()](out, dObj); 01856 } 01857 01859 01866 static ito::tDataType convertCmplxTypeToRealType(ito::tDataType cmplxType) 01867 { 01868 switch(cmplxType) 01869 { 01870 case ito::tInt8: 01871 case ito::tUInt8: 01872 case ito::tInt16: 01873 case ito::tUInt16: 01874 case ito::tInt32: 01875 case ito::tUInt32: 01876 case ito::tFloat32: 01877 case ito::tFloat64: 01878 case ito::tRGBA32: 01879 return cmplxType; 01880 case ito::tComplex64: 01881 return ito::tFloat32; 01882 case ito::tComplex128: 01883 return ito::tFloat64; 01884 } 01885 01886 cv::error(cv::Exception(CV_StsAssert, "Input data type unknown", "", __FILE__, __LINE__)); 01887 return ito::tInt8; 01888 } 01889 01891 01898 static ito::tDataType guessDataTypeFromCVMat(const cv::Mat* mat, ito::RetVal &retval) 01899 { 01900 if (mat) 01901 { 01902 switch(mat->type()) 01903 { 01904 case cv::DataType<ito::int8>::type: 01905 return ito::tInt8; 01906 case cv::DataType<ito::uint8>::type: 01907 return ito::tUInt8; 01908 case cv::DataType<ito::int16>::type: 01909 return ito::tInt16; 01910 case cv::DataType<ito::uint16>::type: 01911 return ito::tUInt16; 01912 case cv::DataType<ito::int32>::type: 01913 return ito::tInt32; 01914 case cv::DataType<ito::uint32>::type: 01915 return ito::tUInt32; 01916 case cv::DataType<ito::float32>::type: 01917 return ito::tFloat32; 01918 case cv::DataType<ito::float64>::type: 01919 return ito::tFloat64; 01920 case cv::DataType<ito::Rgba32>::type: 01921 return ito::tRGBA32; 01922 case cv::DataType<ito::complex64>::type: 01923 return ito::tComplex64; 01924 case cv::DataType<ito::complex128>::type: 01925 return ito::tComplex128; 01926 } 01927 01928 retval += ito::RetVal(ito::retError, 0, "type of cv::Mat is incompatible to ito::DataObject"); 01929 } 01930 else 01931 { 01932 retval += ito::RetVal(ito::retError, 0, "given cv::Mat is NULL."); 01933 } 01934 return ito::tInt8; 01935 } 01936 01937 01938 01939 01941 01950 template<typename _Tp> static inline ito::tDataType getDataType2() 01951 { 01952 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01953 return ito::tInt8; 01954 } 01955 01956 template<> inline ito::tDataType getDataType2<uint8*>() { return ito::tUInt8; } 01957 template<> inline ito::tDataType getDataType2<int8*>() { return ito::tInt8; } 01958 template<> inline ito::tDataType getDataType2<uint16*>() { return ito::tUInt16; } 01959 template<> inline ito::tDataType getDataType2<int16*>() { return ito::tInt16; } 01960 template<> inline ito::tDataType getDataType2<uint32*>() { return ito::tUInt32; } 01961 template<> inline ito::tDataType getDataType2<int32*>() { return ito::tInt32; } 01962 template<> inline ito::tDataType getDataType2<float32*>() { return ito::tFloat32; } 01963 template<> inline ito::tDataType getDataType2<float64*>() { return ito::tFloat64; } 01964 template<> inline ito::tDataType getDataType2<complex64*>() { return ito::tComplex64; } 01965 template<> inline ito::tDataType getDataType2<complex128*>() { return ito::tComplex128; } 01966 template<> inline ito::tDataType getDataType2<Rgba32*>() { return ito::tRGBA32; } 01967 01969 01979 template<typename _Tp> static inline bool isZeroValue(_Tp v, _Tp /*epsilon*/) 01980 { 01981 return v == 0; 01982 } 01983 template<> inline bool isZeroValue(Rgba32 v, Rgba32 /*epsilon*/) 01984 { 01985 return v == Rgba32::zeros(); 01986 } 01987 template<> inline bool isZeroValue(float32 v, float32 epsilon) 01988 { 01989 return v >= epsilon ? false : (v <= -epsilon ? false : true); 01990 } 01991 template<> inline bool isZeroValue(float64 v, float64 epsilon) 01992 { 01993 return v >= epsilon ? false : (v <= -epsilon ? false : true); 01994 } 01995 template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon) 01996 { 01997 return isZeroValue<ito::float32>(v.real(),epsilon.real()) && isZeroValue<ito::float32>(v.imag(),epsilon.real()); 01998 } 01999 template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon) 02000 { 02001 return isZeroValue<ito::float64>(v.real(),epsilon.real()) && isZeroValue<ito::float64>(v.imag(),epsilon.real()); 02002 } 02003 02004 02005 //---------------------------------------------------------------------------------------------------------------------------------- 02006 // friend functions to access private members of DataObject 02007 //---------------------------------------------------------------------------------------------------------------------------------- 02008 } //namespace ito 02009 02010 #endif //__DATAOBJH 02011 02012