itom 1.2.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); 00863 int setAxisDescription(const unsigned int axisNum, const std::string &description); 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 this->create(dimensions, sizes, type, planes, nrOfPlanes); 01319 } 01320 01321 DataObject(const DataObject& copyConstr); 01323 01324 01330 ~DataObject(void) 01331 { 01332 freeData(); 01333 } 01334 01336 DataObject & operator = (const cv::Mat &rhs); 01337 DataObject & operator = (const DataObject &rhs); 01338 DataObject & operator = (const int8 &value); 01339 DataObject & operator = (const uint8 &value); 01340 DataObject & operator = (const int16 &value); 01341 DataObject & operator = (const uint16 &value); 01342 DataObject & operator = (const int32 &value); 01343 DataObject & operator = (const uint32 &value); 01344 DataObject & operator = (const float32 &value); 01345 DataObject & operator = (const float64 &value); 01346 DataObject & operator = (const complex64 &value); 01347 DataObject & operator = (const complex128 &value); 01348 DataObject & operator = (const ito::Rgba32 &value); 01351 DataObject & operator += (const DataObject &rhs); 01352 DataObject & operator += (const float64 &value); 01353 01354 DataObject operator + (const DataObject &rhs); 01355 DataObject operator + (const float64 &value); 01356 01357 DataObject & operator -= (const DataObject &rhs); 01358 DataObject & operator -= (const float64 &value); 01359 01360 DataObject operator - (const DataObject &rhs); 01361 DataObject operator - (const float64 &value); 01362 01363 DataObject & operator *= (const DataObject &rhs); 01364 DataObject & operator *= (const float64 &factor); 01365 01366 DataObject operator * (const DataObject &rhs); 01367 DataObject operator * (const float64 &factor); 01368 01369 // Comparison Operators 01370 DataObject operator < (DataObject &rhs); 01371 DataObject operator > (DataObject &rhs); 01372 DataObject operator <= (DataObject &rhs); 01373 DataObject operator >= (DataObject &rhs); 01374 DataObject operator == (DataObject &rhs); 01375 DataObject operator != (DataObject &rhs); 01376 01377 01378 // bitshift operators 01379 DataObject operator << (const unsigned int shiftbit); 01380 DataObject & operator <<= (const unsigned int shiftbit); 01381 DataObject operator >> (const unsigned int shiftbit); 01382 DataObject & operator >>= (const unsigned int shiftbit); 01383 01384 // bitwise operators 01385 DataObject operator & (const DataObject & rhs); 01386 DataObject & operator &= (const DataObject & rhs); 01387 DataObject operator | (const DataObject & rhs); 01388 DataObject & operator |= (const DataObject & rhs); 01389 DataObject operator ^ (const DataObject & rhs); 01390 DataObject & operator ^= (const DataObject & rhs); 01391 01392 // allocates matrix with zero values 01393 RetVal zeros(const int type); 01394 RetVal zeros(const int size, const int type); 01395 RetVal zeros(const int sizeY, const int sizeX, const int type); 01396 RetVal zeros(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0); 01397 RetVal zeros(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0); 01398 01399 // allocates matrix with all values set to one 01400 RetVal ones(const int type); 01401 RetVal ones(const int size, const int type); 01402 RetVal ones(const int sizeY, const int sizeX, const int type); 01403 RetVal ones(const int sizeZ, const int sizeY, const int sizeX, const int type, const unsigned char continuous = 0); 01404 RetVal ones(const unsigned char dimensions, const int *sizes, const int type, const unsigned char continuous = 0); 01405 01406 // allocates matrix with uniform distributed noise 01407 RetVal rand(const int type, const bool randMode = false); 01408 RetVal rand(const int size, const int type, const bool randMode = false); 01409 RetVal rand(const int sizeY, const int sizeX, const int type, const bool randMode = false); 01410 RetVal rand(const int sizeZ, const int sizeY, const int sizeX, const int type, const bool randMode, const unsigned char continuous = 0); 01411 RetVal rand(const unsigned char dimensions, const int *sizes, const int type, const bool randMode, const unsigned char continuous = 0); 01412 01413 // allocates matrix with eye-matrix representation 01414 RetVal eye(const int type); 01415 RetVal eye(const int size, const int type); 01416 01417 RetVal conj(); 01418 DataObject adj() const; 01419 DataObject trans() const; 01420 01421 //RetVal makeContinuous(void); 01422 01423 DataObject mul(const DataObject &mat2, const double scale = 1.0); 01424 DataObject div(const DataObject &mat2, const double scale = 1.0); 01425 DataObject squeeze() const; 01426 int elemSize() const; 01427 01429 01434 template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) const 01435 { 01436 #if __ITODEBUG 01437 if (m_dims != 2) 01438 { 01439 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01440 } 01441 else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) ) 01442 { 01443 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01444 } 01445 #endif 01446 return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x); 01447 } 01448 01450 01455 template<typename _Tp> _Tp& at(const unsigned int y, const unsigned int x) 01456 { 01457 #if __ITODEBUG 01458 if (m_dims != 2) 01459 { 01460 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01461 } 01462 else if (((int)x >= m_size[1]) || ((int)y >= m_size[0]) ) 01463 { 01464 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01465 } 01466 01467 #endif 01468 return (*(cv::Mat_<_Tp> *)(m_data[0]))(y, x); 01469 } 01470 01472 01478 template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) const 01479 { 01480 #if __ITODEBUG 01481 if (m_dims != 3) 01482 { 01483 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01484 } 01485 else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0]))) 01486 { 01487 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01488 } 01489 #endif 01490 01491 return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x); 01492 } 01493 01495 01501 template<typename _Tp> _Tp& at(const unsigned int z, const unsigned int y, const unsigned int x) 01502 { 01503 #if __ITODEBUG 01504 if (m_dims != 3) 01505 { 01506 cv::error(cv::Exception(CV_StsAssert, "Dimension mismatch while addressing data field", "", __FILE__, __LINE__)); 01507 } 01508 else if (((int)x >= m_size[2]) || ((int)y >= m_size[1]) || (((int)z + m_roi[0]) >= (m_roi[0] + m_size[0]))) 01509 { 01510 cv::error(cv::Exception(CV_StsAssert, "Index out of bounds", "", __FILE__ , __LINE__)); 01511 } 01512 #endif 01513 return (*(cv::Mat_<_Tp> *)(m_data[z + m_roi[0]]))(y, x); 01514 } 01515 01517 01522 template<typename _Tp> _Tp& at(const unsigned int *idx) const //idx is in virtual order 01523 { 01524 int matNum = 0; 01525 01526 matIdxToNum(idx, &matNum); 01527 01528 return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]); 01529 } 01530 01532 01537 template<typename _Tp> _Tp& at(const unsigned int *idx) //idx is in virtual order 01538 { 01539 int matNum = 0; 01540 01541 matIdxToNum(idx, &matNum); 01542 01543 return (*(cv::Mat_<_Tp> *)(m_data[matNum]))(idx[m_dims - 2], idx[m_dims - 1]); 01544 } 01545 01546 DataObject at(const ito::Range &rowRange, const ito::Range &colRange); 01547 DataObject at(ito::Range *ranges); 01549 01550 01556 uchar* rowPtr(const int matNum, const int y) 01557 { 01558 int matIndex = seekMat(matNum); 01559 return ((cv::Mat*)m_data[matIndex])->ptr(y); 01560 } 01561 01563 01569 const uchar* rowPtr(const int matNum, const int y) const 01570 { 01571 int matIndex = seekMat(matNum); 01572 return ((cv::Mat*)m_data[matIndex])->ptr(y); 01573 } 01574 01575 DataObject row(const int selRow); 01576 DataObject col(const int selCol); 01577 01578 DataObject toGray(const int destinationType = ito::tUInt8); 01579 01580 // ROI 01581 DataObject & adjustROI(const int dtop, const int dbottom, const int dleft, const int dright); 01582 DataObject & adjustROI(const unsigned char dims, const int *lims); 01583 RetVal locateROI(int *wholeSizes, int *offsets); 01584 RetVal locateROI(int *lims); 01586 01587 01602 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 01603 01605 01629 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 01630 01631 //---------------------------------------------------------------------------------------------------------------------------------- 01633 /* 01634 \param [in] src is any variable whose type is checked 01635 \return retOk if both types are equal, retError if they are not equal or if the type of src is unknown 01636 */ 01637 template<typename _Tp> RetVal checkType(const _Tp *src) //must be inline since function template! 01638 { 01639 try 01640 { 01641 if(m_type == ito::getDataType(src)) 01642 { 01643 return ito::retOk; 01644 } 01645 return RetVal(retError,0,"CheckType failed: types are not equal"); 01646 } 01647 catch(cv::Exception /*&ex*/) 01648 { 01649 return RetVal(retError,0,"Error during Type-Check. Type not templated"); 01650 } 01651 } 01652 01653 // 01654 template<typename T2> operator T2 (); 01656 template<typename _Tp> RetVal linspace(const _Tp start, const _Tp end, const _Tp inc, const int transposed); 01657 01658 }; 01659 01660 //template<> DATAOBJ_EXPORT RetVal ito::DataObject::linspace<ito::int8>(const ito::int8 /*start*/, const ito::int8 /*end*/, const ito::int8 /*inc*/, const int /*transposed*/); 01661 //template<> DATAOBJ_EXPORT RetVal ito::DataObject::linspace<ito::uint8>(const ito::uint8 /*start*/, const ito::uint8 /*end*/, const ito::uint8 /*inc*/, const int /*transposed*/); 01662 01663 01664 //---------------------------------------------------------------------------------------------------------------------------------- 01665 // functions for DataObject in namespace ITO, which are NOT member functions 01666 //---------------------------------------------------------------------------------------------------------------------------------- 01667 DataObject DATAOBJ_EXPORT abs(const DataObject &dObj); 01668 DataObject DATAOBJ_EXPORT arg(const DataObject &dObj); 01669 DataObject DATAOBJ_EXPORT real(const DataObject &dObj); 01670 DataObject DATAOBJ_EXPORT imag(const DataObject &dObj); 01672 DataObject DATAOBJ_EXPORT makeContinuous(const DataObject &dObj); 01674 template<typename _Tp, typename _T2> RetVal CastFunc(const DataObject *dObj, DataObject *resObj, double alpha = 1.0, double beta = 0.0); 01675 01676 //RetVal minMaxLoc(const DataObject &dObj, double *minVal, double *maxVal, int *minPos = NULL, int *maxPos = NULL); 01677 01679 01686 template<typename _Tp> _Tp numberConversion(ito::tDataType fromType, void *scalar) 01687 { 01688 //_Tp retValue = 0; 01689 _Tp retValue; 01690 01691 switch(fromType) 01692 { 01693 case ito::tUInt8: 01694 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint8*>(scalar))); 01695 break; 01696 case ito::tInt8: 01697 retValue = cv::saturate_cast<_Tp>(*(static_cast<int8*>(scalar))); 01698 break; 01699 case ito::tUInt16: 01700 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint16*>(scalar))); 01701 break; 01702 case ito::tInt16: 01703 retValue = cv::saturate_cast<_Tp>(*(static_cast<int16*>(scalar))); 01704 break; 01705 case ito::tUInt32: 01706 retValue = cv::saturate_cast<_Tp>(*(static_cast<uint32*>(scalar))); 01707 break; 01708 case ito::tInt32: 01709 retValue = cv::saturate_cast<_Tp>(*(static_cast<int32*>(scalar))); 01710 break; 01711 case ito::tFloat32: 01712 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float32*>(scalar))); 01713 break; 01714 case ito::tFloat64: 01715 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::float64*>(scalar))); 01716 break; 01717 case ito::tComplex64: 01718 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex64*>(scalar))); 01719 break; 01720 case ito::tComplex128: 01721 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::complex128*>(scalar))); 01722 break; 01723 case ito::tRGBA32: 01724 retValue = cv::saturate_cast<_Tp>(*(static_cast<ito::Rgba32*>(scalar))); 01725 break; 01726 default: 01727 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01728 retValue = 0; 01729 } 01730 01731 return retValue; 01732 }; 01733 01734 //template<> ito::Rgba32 numberConversion<ito::Rgba32>(ito::tDataType fromType, void *scalar) 01735 //{ 01736 // _Tp retValue = 0; 01737 // 01738 // switch(fromType) 01739 // { 01740 // case ito::tUInt8: 01741 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint8*>(scalar))); 01742 // break; 01743 // case ito::tInt8: 01744 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int8*>(scalar))); 01745 // break; 01746 // case ito::tUInt16: 01747 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint16*>(scalar))); 01748 // break; 01749 // case ito::tInt16: 01750 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int16*>(scalar))); 01751 // break; 01752 // case ito::tUInt32: 01753 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<uint32*>(scalar))); 01754 // break; 01755 // case ito::tInt32: 01756 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<int32*>(scalar))); 01757 // break; 01758 // case ito::tFloat32: 01759 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float32*>(scalar))); 01760 // break; 01761 // case ito::tFloat64: 01762 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::float64*>(scalar))); 01763 // break; 01764 // case ito::tComplex64: 01765 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex64*>(scalar))); 01766 // break; 01767 // case ito::tComplex128: 01768 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::complex128*>(scalar))); 01769 // break; 01770 // case ito::tRGBA32: 01771 // retValue = cv::saturate_cast<ito::Rgba32>(*(static_cast<ito::Rgba32*>(scalar))); 01772 // break; 01773 // default: 01774 // cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01775 // retValue = 0; 01776 // } 01777 // 01778 // return retValue; 01779 //} 01780 01781 //---------------------------------------------------------------------------------------------------------------------------------- 01782 // cout 01783 //---------------------------------------------------------------------------------------------------------------------------------- 01784 template<typename _Tp> static std::ostream& coutFunc(std::ostream& out, const DataObject& dObj) 01785 { 01786 //cv::Mat_<_Tp> *cvMat = NULL; 01787 int numMats = dObj.calcNumMats(); 01788 int tMat = 0; 01789 01790 if (dObj.getDims() == 0) 01791 { 01792 std::cout << "DataObject()\n" << std::endl; 01793 } 01794 else 01795 { 01796 std::cout << "DataObject(size=[" << dObj.getSize(0); 01797 for (int dim = 1; dim < dObj.getDims(); ++dim) 01798 { 01799 std::cout << "x" << dObj.getSize(dim); 01800 } 01801 std::cout << "]\n" << std::endl; 01802 01803 int *idx = new int[dObj.getDims()]; 01804 01805 01806 for (int nMat = 0; nMat < numMats; nMat++) 01807 { 01808 tMat = dObj.seekMat(nMat, numMats); 01809 //std::cout << tMat + 1 << "->("; 01810 01811 dObj.matNumToIdx(tMat, idx); 01812 std::cout << "["; 01813 for (int i = 0; i < dObj.getDims() - 2; ++i) 01814 { 01815 std::cout << idx[i] << ","; 01816 } 01817 std::cout << ":,:]->("; 01818 01819 std::cout << cv::format( (*((cv::Mat_<_Tp> *)((dObj.get_mdata())[tMat]))) , "numpy" ) << std::endl << std::endl; 01820 01821 std::cout << ")" << "\n" << std::endl; 01822 } 01823 01824 delete[] idx; 01825 01826 std::cout << ")" << "\n" << std::endl; 01827 } 01828 return out; 01829 01830 } 01831 01832 typedef std::ostream& (*tCoutFunc)(std::ostream& out, const DataObject& dObj); 01833 01834 static tCoutFunc fListCout[] = 01835 { 01836 coutFunc<int8>, 01837 coutFunc<uint8>, 01838 coutFunc<int16>, 01839 coutFunc<uint16>, 01840 coutFunc<int32>, 01841 coutFunc<uint32>, 01842 coutFunc<ito::float32>, 01843 coutFunc<ito::float64>, 01844 coutFunc<ito::complex64>, 01845 coutFunc<ito::complex128>, 01846 coutFunc<ito::Rgba32> 01847 }; 01848 01849 static inline std::ostream& operator << (std::ostream& out, const DataObject& dObj) 01850 { 01851 return fListCout[dObj.getType()](out, dObj); 01852 } 01853 01855 01862 static ito::tDataType convertCmplxTypeToRealType(ito::tDataType cmplxType) 01863 { 01864 switch(cmplxType) 01865 { 01866 case ito::tInt8: 01867 case ito::tUInt8: 01868 case ito::tInt16: 01869 case ito::tUInt16: 01870 case ito::tInt32: 01871 case ito::tUInt32: 01872 case ito::tFloat32: 01873 case ito::tFloat64: 01874 case ito::tRGBA32: 01875 return cmplxType; 01876 case ito::tComplex64: 01877 return ito::tFloat32; 01878 case ito::tComplex128: 01879 return ito::tFloat64; 01880 } 01881 01882 cv::error(cv::Exception(CV_StsAssert, "Input data type unknown", "", __FILE__, __LINE__)); 01883 return ito::tInt8; 01884 } 01885 01887 01894 static ito::tDataType guessDataTypeFromCVMat(const cv::Mat* mat, ito::RetVal &retval) 01895 { 01896 //this method was added 2014-05-09 without changing the binary compatibility of the dataObject library 01897 if (mat) 01898 { 01899 switch(mat->type()) 01900 { 01901 case cv::DataType<ito::int8>::type: 01902 return ito::tInt8; 01903 case cv::DataType<ito::uint8>::type: 01904 return ito::tUInt8; 01905 case cv::DataType<ito::int16>::type: 01906 return ito::tInt16; 01907 case cv::DataType<ito::uint16>::type: 01908 return ito::tUInt16; 01909 case cv::DataType<ito::int32>::type: 01910 return ito::tInt32; 01911 case cv::DataType<ito::uint32>::type: 01912 return ito::tUInt32; 01913 case cv::DataType<ito::float32>::type: 01914 return ito::tFloat32; 01915 case cv::DataType<ito::float64>::type: 01916 return ito::tFloat64; 01917 case cv::DataType<ito::Rgba32>::type: 01918 return ito::tRGBA32; 01919 case cv::DataType<ito::complex64>::type: 01920 return ito::tComplex64; 01921 case cv::DataType<ito::complex128>::type: 01922 return ito::tComplex128; 01923 } 01924 01925 retval += ito::RetVal(ito::retError, 0, "type of cv::Mat is incompatible to ito::DataObject"); 01926 } 01927 else 01928 { 01929 retval += ito::RetVal(ito::retError, 0, "given cv::Mat is NULL."); 01930 } 01931 return ito::tInt8; 01932 } 01933 01934 01935 01936 01938 01947 template<typename _Tp> static inline ito::tDataType getDataType2() 01948 { 01949 cv::error(cv::Exception(CV_StsAssert, "Input value type unkown", "", __FILE__, __LINE__)); 01950 return ito::tInt8; 01951 } 01952 01953 template<> inline ito::tDataType getDataType2<uint8*>() { return ito::tUInt8; } 01954 template<> inline ito::tDataType getDataType2<int8*>() { return ito::tInt8; } 01955 template<> inline ito::tDataType getDataType2<uint16*>() { return ito::tUInt16; } 01956 template<> inline ito::tDataType getDataType2<int16*>() { return ito::tInt16; } 01957 template<> inline ito::tDataType getDataType2<uint32*>() { return ito::tUInt32; } 01958 template<> inline ito::tDataType getDataType2<int32*>() { return ito::tInt32; } 01959 template<> inline ito::tDataType getDataType2<float32*>() { return ito::tFloat32; } 01960 template<> inline ito::tDataType getDataType2<float64*>() { return ito::tFloat64; } 01961 template<> inline ito::tDataType getDataType2<complex64*>() { return ito::tComplex64; } 01962 template<> inline ito::tDataType getDataType2<complex128*>() { return ito::tComplex128; } 01963 template<> inline ito::tDataType getDataType2<Rgba32*>() { return ito::tRGBA32; } 01964 01966 01976 template<typename _Tp> static inline bool isZeroValue(_Tp v, _Tp /*epsilon*/) 01977 { 01978 return v == 0; 01979 } 01980 template<> inline bool isZeroValue(Rgba32 v, Rgba32 /*epsilon*/) 01981 { 01982 return v == Rgba32::zeros(); 01983 } 01984 template<> inline bool isZeroValue(float32 v, float32 epsilon) 01985 { 01986 return v >= epsilon ? false : (v <= -epsilon ? false : true); 01987 } 01988 template<> inline bool isZeroValue(float64 v, float64 epsilon) 01989 { 01990 return v >= epsilon ? false : (v <= -epsilon ? false : true); 01991 } 01992 template<> inline bool isZeroValue(std::complex<ito::float32> v, std::complex<ito::float32> epsilon) 01993 { 01994 return isZeroValue<ito::float32>(v.real(),epsilon.real()) && isZeroValue<ito::float32>(v.imag(),epsilon.real()); 01995 } 01996 template<> inline bool isZeroValue(std::complex<ito::float64> v, std::complex<ito::float64> epsilon) 01997 { 01998 return isZeroValue<ito::float64>(v.real(),epsilon.real()) && isZeroValue<ito::float64>(v.imag(),epsilon.real()); 01999 } 02000 02001 02002 //---------------------------------------------------------------------------------------------------------------------------------- 02003 // friend functions to access private members of DataObject 02004 //---------------------------------------------------------------------------------------------------------------------------------- 02005 } //namespace ito 02006 02007 #endif //__DATAOBJH 02008 02009