cvutMatrix.h
上传用户:jiayuled
上传日期:2020-03-04
资源大小:9338k
文件大小:16k
源码类别:

OpenCV

开发平台:

C/C++

  1. /************************************************************************
  2. 没有考虑不同数据类型但相同矩阵形式之间的各种操作
  3. *************************************************************************/
  4. #ifndef CVUT_MATRIX_H
  5. #define CVUT_MATRIX_H
  6. #include "cv.h"
  7. #include <iostream>
  8. #include <sstream>
  9. #include <string>
  10. #include <typeinfo>
  11. using namespace std;
  12. //#pragma comment(lib,"cxcore.lib")
  13. namespace cvutMatrix {
  14. /************************************************************************
  15. Class Matrix
  16. *************************************************************************/
  17. template <typename T>
  18. class Matrix {
  19. public:
  20. T* data;
  21. int rows;
  22. int cols;
  23. int channels;
  24. CvMat* cvmat;
  25. public:
  26. /************************************************************************
  27. constructor
  28. *************************************************************************/
  29. Matrix(int rows,int cols,int channels=1,const T* arr=NULL) {
  30. int type=0;
  31. if (0 == strcmp(typeid(*data).name(),"unsigned char")) {
  32. type = 0;
  33. } else if (0 == strcmp(typeid(*data).name(),"char")) {
  34. type = 1;
  35. } else if (0 == strcmp(typeid(*data).name(),"short")) {
  36. type = 2;
  37. } else if (0 == strcmp(typeid(*data).name(),"unsigned short")) {
  38. type = 3;
  39. } else if (0 == strcmp(typeid(*data).name(),"int")) {
  40. type = 4;
  41. } else if (0 == strcmp(typeid(*data).name(),"float")) {
  42. type = 5;
  43. } else if (0 == strcmp(typeid(*data).name(),"double")) {
  44. type = 6;
  45. } else {
  46. cerr<<"unsupported matrix type!n";
  47. exit(1);
  48. }
  49. cvmat = cvCreateMat(rows,cols,type+8*(channels-1));
  50. data = (T*)cvmat->data.ptr;
  51. this->rows = rows;
  52. this->cols = cols;
  53. this->channels=channels;
  54. bool user_data=false;
  55. if (arr !=NULL) 
  56. user_data=true;
  57. for (int i=0;i<rows;i++) {
  58. for (int j=0;j<cols;j++) {
  59. for (int k=0;k<channels;k++) {
  60. if (user_data)
  61. data[i*cols*channels+j*channels+k]=arr[i*cols*channels+j*channels+k];
  62. else
  63. data[i*cols*channels+j*channels+k]=0;
  64. }
  65. }
  66. }
  67. };
  68. Matrix(CvMat* src) {
  69. cvmat = cvCloneMat(src);
  70. data = (T*)src->data.ptr;
  71. rows = src->rows;
  72. cols = src->cols;
  73. channels=cvmat->step/cols/sizeof(T);
  74. };
  75. Matrix(Matrix<T>& src) {
  76. cvmat=cvCloneMat(src.cvmat);
  77. data = (T*)(src.cvmat->data.ptr);
  78. rows = src.rows;
  79. cols = src.cols;
  80. channels=src.channels;
  81. };
  82. /************************************************************************
  83. deconstructor
  84. *************************************************************************/
  85. ~Matrix() {
  86. cvReleaseMat(&cvmat);
  87. data=NULL;
  88. };
  89. /************************************************************************
  90. access matrix element
  91. *************************************************************************/
  92. T& operator () (int i_row,int i_col,int i_channel=0) {
  93. if (i_row>=0 && i_row<rows && i_col>=0 && i_col<cols && i_channel>=0 && i_channel<channels)
  94. return data[i_row*cols+i_col*channels+i_channel];
  95. else {
  96. cerr<<"matrix access out of range"<<endl;
  97. exit(1);
  98. }
  99. };
  100. /************************************************************************
  101. overload = (Matrix = Matrix)
  102. *************************************************************************/
  103. Matrix<T>& operator =(Matrix<T>& src) {
  104. if (!mat_type_cmp(*this,src)) {
  105. cerr<<"matrix type unmatch!n";
  106. exit(1);
  107. }
  108. for (int i=0;i<rows;i++) {
  109. for (int j=0;j<cols;j++) {
  110. for (int k=0;k<channels;k++) {
  111. data[i*cols*channels+j*channels+k]=src.data[i*cols*channels+j*channels+k];
  112. }
  113. }
  114. }
  115. return *this;
  116. };
  117. /************************************************************************
  118. overload + (matrix + matrix)
  119. *************************************************************************/
  120. Matrix<T> operator + (Matrix<T>& src) {
  121. if (!mat_type_cmp(*this,src)) {
  122. cerr<<"matrix type unmatch!n";
  123. exit(1);
  124. }
  125. Matrix<T> temp(*this);
  126. cvAdd(cvmat,src.cvmat,temp.cvmat);
  127. return temp;
  128. };
  129. /************************************************************************
  130. overload += (matrix += matrix)
  131. *************************************************************************/
  132. Matrix<T>& operator +=(Matrix<T>& src) {
  133. if (!mat_type_cmp(*this,src)) {
  134. cerr<<"matrix type unmatch!n";
  135. exit(1);
  136. }
  137. cvAdd(cvmat,src.cvmat,cvmat);
  138. return *this;
  139. };
  140. /************************************************************************
  141. overload + (matrix + number)
  142. *************************************************************************/
  143. Matrix<T> operator + (double num) {
  144. Matrix<T> temp(*this);
  145. for (int i=0;i<rows;i++) {
  146. for (int j=0;j<cols;j++) {
  147. for (int k=0;k<channels;k++) {
  148. temp.data[i*cols*channels+j*channels+k]+=num;
  149. }
  150. }
  151. }
  152. return temp;
  153. };
  154. /************************************************************************
  155. overload += (matrix += number)
  156. *************************************************************************/
  157. Matrix<T>& operator +=(double num) {
  158. for (int i=0;i<rows;i++) {
  159. for (int j=0;j<cols;j++) {
  160. for (int k=0;k<channels;k++) {
  161. data[i*cols*channels+j*channels+k]+=num;
  162. }
  163. }
  164. }
  165. return *this;
  166. };
  167. /************************************************************************
  168. overload - (matrix - matrix)
  169. *************************************************************************/
  170. Matrix<T> operator - (Matrix<T>& src) {
  171. if (!mat_type_cmp(*this,src)) {
  172. cerr<<"matrix type unmatch!n";
  173. exit(1);
  174. }
  175. Matrix<T> temp(*this);
  176. cvSub(cvmat,src.cvmat,temp.cvmat);
  177. return temp;
  178. };
  179. /************************************************************************
  180. overload -= (matrix -= matrix)
  181. *************************************************************************/
  182. Matrix<T>& operator -=(Matrix<T>& src) {
  183. if (!mat_type_cmp(*this,src)) {
  184. cerr<<"matrix type unmatch!n";
  185. exit(1);
  186. }
  187. cvSub(cvmat,src.cvmat,cvmat);
  188. return *this;
  189. };
  190. /************************************************************************
  191. overload - (matrix - number)
  192. *************************************************************************/
  193. Matrix<T> operator - (double num) {
  194. Matrix<T> temp(*this);
  195. return temp+=(-num);;
  196. };
  197. /************************************************************************
  198. overload -= (matrix -= number)
  199. *************************************************************************/
  200. Matrix<T>& operator -=(double num) {
  201. return *this+=(-num);
  202. };
  203. /************************************************************************
  204. overload * (matrix * matrix)
  205. *************************************************************************/
  206. Matrix<T> operator * (Matrix<T>& src) {
  207. if (!can_mult(*this,src)) {
  208. cerr<<"matrix multiply fail!n";
  209. exit(1);
  210. }
  211. Matrix<T> temp(rows,src.cols,channels);
  212. cvMatMul(cvmat,src.cvmat,temp.cvmat);
  213. return temp;
  214. };
  215. /************************************************************************
  216. overload * (matrix * number)
  217. *************************************************************************/
  218. Matrix<T> operator * (double num) {
  219. Matrix<T> temp(*this);
  220. for (int i=0;i<rows;i++) {
  221. for (int j=0;j<cols;j++) {
  222. for (int k=0;k<channels;k++) {
  223. temp.data[i*cols*channels+j*channels+k] *= num;
  224. }
  225. }
  226. }
  227. return temp;
  228. };
  229. /************************************************************************
  230. overload *= (matrix *= number)
  231. *************************************************************************/
  232. Matrix<T>& operator *=(double num) {
  233. for (int i=0;i<rows;i++) {
  234. for (int j=0;j<cols;j++) {
  235. for (int k=0;k<channels;k++) {
  236. data[i*cols*channels+j*channels+k]*=num;
  237. }
  238. }
  239. }
  240. return *this;
  241. };
  242. /************************************************************************
  243. compare two matrixes (matrix == matrix)
  244. regardless of element type
  245. *************************************************************************/
  246. bool operator == (const Matrix<T>& src) {
  247. if (!mat_type_cmp(*this,src))
  248. return false;
  249. for (int i=0;i<src.rows;i++) {
  250. for (int j=0;j<src.cols;j++) {
  251. for (int k=0;k<src.channels;k++) {
  252. if (src.data[i*src.cols*src.channels+j*src.channels+k] !=
  253. data[i*src.cols*src.channels+j*src.channels+k]) 
  254. {
  255. return false;
  256. }
  257. }
  258. }
  259. }
  260. return true;
  261. };
  262. /************************************************************************
  263. set matrix identity
  264. *************************************************************************/
  265. void identity() {
  266. if (cols != rows) {
  267. cerr<<"identity fail! non-spuare!n";
  268. exit(1);
  269. }
  270. for (int i=0;i<cols;i++) {
  271. for (int j=0;j<rows;j++) {
  272. for (int k=0;k<channels;k++)
  273. data[i*cols*channels+j*channels+k]=(i == j)?1.0:0.0;
  274. }
  275. }
  276. };
  277. /************************************************************************
  278.        get row
  279. *************************************************************************/
  280. Matrix<T> get_row(int index) {
  281. if (index<0 || index>=rows) {
  282. cerr<<"out of range!n";
  283. exit(1);
  284. }
  285. Matrix<T> temp(1,cols,channels);
  286. for (int i=0;i<cols;i++) {
  287. for (int j=0;j<channels;j++) {
  288. temp(0,i,j) = data[index*cols*channels+i*channels+j];
  289. }
  290. }
  291. return temp;
  292. };
  293. /************************************************************************
  294.        get rows
  295. *************************************************************************/
  296. Matrix<T> get_rows(int first,int last) {
  297. if (first<0 || first>=rows || last<0 || last>=rows || first>last) {
  298. cerr<<"out of range!n";
  299. exit(1);
  300. }
  301. Matrix<T> temp(last-first+1,cols,channels);
  302. for (int t=0;t<last-first+1;t++) {
  303. for (int i=0;i<cols;i++) {
  304. for (int j=0;j<channels;j++) {
  305. temp(t,i,j) = data[(t+first)*cols*channels+i*channels+j];
  306. }
  307. }
  308. }
  309. return temp;
  310. };
  311. /************************************************************************
  312.        get column
  313. *************************************************************************/
  314. Matrix<T> get_col(int index) {
  315. if (index<0 || index>=cols) {
  316. cerr<<"out of range!n";
  317. exit(1);
  318. }
  319. Matrix<T> temp(rows,1,channels);
  320. for (int i=0;i<rows;i++) {
  321. for (int j=0;j<channels;j++) {
  322. temp(i,0,j) = data[i*cols*channels+index*channels+j];
  323. }
  324. }
  325. return temp;
  326. };
  327. /************************************************************************
  328.        get columns
  329. *************************************************************************/
  330. Matrix<T> get_cols(int first,int last) {
  331. if (first<0 || first>=cols || last<0 || last>=cols || first>last) {
  332. cerr<<"out of range!n";
  333. exit(1);
  334. }
  335. Matrix<T> temp(rows,last-first+1,channels);
  336. for (int t=0;t<rows;t++) {
  337. for (int i=0;i<last-first+1;i++) {
  338. for (int j=0;j<channels;j++) {
  339. temp(t,i,j) = data[t*cols*channels+(i+first)*channels+j];
  340. }
  341. }
  342. }
  343. return temp;
  344. };
  345. /************************************************************************
  346.        get sub-matrix
  347. *************************************************************************/
  348. Matrix<T> submat(int first_row,int last_row,int first_col,int last_col,int first_channel,int last_channel) {
  349. if (first_row<0 || first_row>=rows ||
  350. last_row<0 || last_row>=rows || first_row>last_row ||
  351. first_col<0 || first_col>=cols ||
  352. last_col<0 || last_col>=cols || first_col>last_col ||
  353. first_channel<0 || first_channel>=channels ||
  354. last_channel<0 || last_channel>=channels || first_channel>last_channel) 
  355. {
  356. cerr<<"out of range!n";
  357. exit(1);
  358. }
  359. Matrix<T> temp(last_row-first_row+1,last_col-first_col+1,last_channel-first_channel+1);
  360. for (int i=0;i<last_row-first_row+1;i++) {
  361. for (int j=0;j<last_col-first_col+1;j++) {
  362. for (int t=0;t<last_channel-first_channel+1;t++) {
  363. temp(i,j,t) = data[(i+first_row)*cols*channels+(j+first_col)*channels+t];
  364. }
  365. }
  366. }
  367. return temp;
  368. };
  369. /************************************************************************
  370.        get struct information of matrix
  371. *************************************************************************/
  372. string info() {
  373. stringstream stream;
  374. string rows,cols,cha;
  375. stream<<rows;
  376. stream>>rows;
  377. stream.clear();
  378. stream<<cols;
  379. stream>>cols;
  380. stream.clear();
  381. stream<<channels;
  382. stream>>cha;
  383. stream.clear();
  384. string s = "elem type : ";
  385. s+=typeid(*data).name();
  386. s+="nrows : ";
  387. s+=rows;
  388. s+="ncols : ";
  389. s+=cols;
  390. s+="nchannels : ";
  391. s+=cha;
  392. s+='n';
  393. return s;
  394. };
  395. }; /* class Matrix */
  396.    /************************************************************************
  397. Matrix tool function
  398.    *************************************************************************/ 
  399.    /************************************************************************
  400. whether matrix is square
  401.    *************************************************************************/
  402.    template <typename T>
  403.    bool is_square (const Matrix<T>& src) {
  404.    if (src.rows == src.cols)
  405.    return true;
  406.    else
  407.    return false;
  408.    };
  409.    
  410.    /************************************************************************
  411. whether matrix can mult
  412.    *************************************************************************/
  413.    template <typename T>
  414. bool can_mult(const Matrix<T>& mat1,const Matrix<T>& mat2) {
  415.    if ((mat1.cols == mat2.rows) && (mat1.channels == mat2.channels))
  416.    return true;
  417.    else
  418.    return false;
  419.    };
  420.    
  421.    /************************************************************************
  422. whether two matrix are same
  423. regardless of element type
  424.    *************************************************************************/
  425.    template <typename T>
  426. bool mat_type_cmp (const Matrix<T>& mat1,const Matrix<T>& mat2) {
  427.    if (mat1.channels != mat2.channels)
  428.    return false;
  429.    if (mat1.rows != mat2.rows)
  430.    return false;
  431.    if (mat1.cols != mat2.cols)
  432.    return false;
  433.    return true;
  434.    };
  435.    
  436.    /************************************************************************
  437. whether the element types of two matrix are same
  438.    *************************************************************************/
  439.    template <typename T,typename P>
  440. bool mat_data_type_cmp (const Matrix<T>& mat1,const Matrix<P>& mat2) {
  441.    if (typeid(*mat1.data) == typeid(*mat2.data))
  442.    return true;
  443.    return false;
  444.    };
  445.    
  446.    /************************************************************************
  447. matrix transpose
  448.    *************************************************************************/
  449.    template <typename T>
  450. Matrix<T> transpose(Matrix<T>& src) {
  451.    Matrix<T> temp(src.cols,src.rows,src.channels);
  452.    cvTranspose(src.cvmat,temp.cvmat);
  453.    return temp;
  454.    };
  455.    
  456.    /************************************************************************
  457. invert matrix
  458.    *************************************************************************/
  459.    template <typename T>
  460. Matrix<T> invert(Matrix<T>& src,int method=CV_SVD) {
  461.    if (!is_square(src)) {
  462.    cerr<<"can not invert a non-squre matrix!n";
  463.    exit(1);
  464.    }
  465.    Matrix<T> temp(src);
  466.    cvInvert(src.cvmat,temp.cvmat,method);
  467.    return temp;
  468.    };
  469.    
  470.    /************************************************************************
  471. matrix's det
  472.    *************************************************************************/
  473.    template <typename T>
  474. double det(Matrix<T>& src) {
  475.    if (!is_square(src)) {
  476.    cerr<<"con not get det from non-square matrix!n";
  477.    exit(1);
  478.    }
  479.    return cvDet(src.cvmat);
  480.    };
  481.    
  482.    template <typename T>
  483.    ostream& operator << (ostream& out,Matrix<T>& src) {
  484.    stringstream stream;
  485.    string data="";
  486.    for (int i=0;i<src.rows;i++) {
  487.    out<<'{';
  488.    for (int j=0;j<src.cols;j++) {
  489.    if (src.channels != 1)
  490.        out<<'{';
  491.    for (int k=0;k<src.channels;k++) {
  492.    stream.clear();
  493.    stream<<src.data[i*src.cols*src.channels+j*src.channels+k];
  494.    stream>>data;
  495.    out<<data;
  496.    if (k < src.channels-1)
  497.    out<<',';
  498.    }
  499.    if (src.channels != 1)
  500.        out<<'}';
  501.    if (j < src.cols-1)
  502.    out<<',';
  503.    }
  504.    out<<'}'<<'n';
  505.    }
  506.    return out;
  507.    };
  508.    
  509. } /* namespace cvutMatrix */
  510. #endif /* CVUT_MATRIX_H */