[1] Where are the cv::Mat data structure constructors explicitly (in C/C++) defined in the OpenCV source code?
I assume a cv::Mat data structure is dynamically allocated to the heap when something like
cv::Mat mat(rows, cols, type);
is called, but could neither find the ANSI C or C++ implementation in
opencv / modules / core / src / matrix.cpp nor in
opencv / modules / core / src / datastructs.cpp.
SOLVED: cv::Mat is allocated with a fastMalloc() in matrix.cpp. this is performed within the cv::Mat:create() function.
[2] Further, I'm curious to know where in hardware the cv::Mat will be located when image processing operations are performed:
. always in 'main memory' (SDRAM),
. always in on-chip caches (SRAM),
. or some combination of the two?
cv::Mat mat(rows, cols, type);
This is inline constructor and it's implemented in core/mat.hpp:
inline Mat::Mat(int _rows, int _cols, int _type) : size(&rows)
{
initEmpty();
create(_rows, _cols, _type);
}
The actual constructors are in
... / core / core.hpp
class CV_EXPORTS Mat
{
public:
//! default constructor
Mat();
//! constructs 2D matrix of the specified size and type
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
Mat(int rows, int cols, int type);
Mat(Size size, int type);
//! constucts 2D matrix and fills it with the specified value _s.
Mat(int rows, int cols, int type, const Scalar& s);
Mat(Size size, int type, const Scalar& s);
//! constructs n-dimensional matrix
Mat(int ndims, const int* sizes, int type);
Mat(int ndims, const int* sizes, int type, const Scalar& s);
//! copy constructor
Mat(const Mat& m);
//! constructor for matrix headers pointing to user-allocated data
Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
.....
};
Related
I have a matrix and scalar, lets call the matrix A. if I multiply the scalar to the matrix , when the scalar is on the right(2*A) it multiply all the indexes of the matrix by 2. BUT when I multiply the matrix with scalar on the left(A*2) it doesn't work!.(its should do as 2*A).
This is part of class(with members):
class Mat
{
private:
int **matArray;
int rows;
int cols;
bool validMat;
public:
.../*functions*/
};
this is the function when of the right multiply:
Mat Mat::operator*(int scalarToMultiply){
if(!validMat)
{
Mat resultOperator(0,0);
return (resultOperator);
}
//Mat resultOperator(matToAdd.cols,matToAdd.rows);
Mat resultOperator(cols,rows);
for (int i=0; i<rows; i++){
for (int j=0; j<cols; j++){
resultOperator.matArray[i][j]=matArray[i][j]*scalarToMultiply;
}
}
return (resultOperator);
}
How do I do the other way?
You just need to write the right-hand-side operator:
Mat operator*(int scalar, const Mat& rhs) {
return rhs * scalar;
}
You can define operator* as a free function (after the class):
Mat operator*(int scalarToMultiply, const Mat& mat) { ... }
And if you need access to the private members, make it a friend of your class by adding
friend Mat operator*(int scalarToMultiply, const Mat& mat);
to your class.
If you plan to write operator*, you probably also want to support operator*=. To make your life easier, you can use libraries like Boost.Operators or df.operators. That way you only need to implement the basic operators and the libraries take care of generating the rest for you.
In order to have the int on the left hand side you need to have free function that has two parameters. The you can call the Mat overloaded function inside free function.
Mat operator*(int lhs, Mat rhs)
{
return rhs * lhs;
}
template <class T>
class Matrix
{
private:
T** data; // matrix elements stored here
int rows; // number of rows
int cols; // number of columns
public:
Matrix(int numRows = 0, int numCols = 0); // makes storage allocation but leaves it uninitialized, for 0,0 dont allocate memory
Matrix(T const* const* inputData, int numRows, int numCols);
Matrix(const Matrix& rhs);
~Matrix();
I have to do implementation and normally I can. But this time I can't figure out what to do with T**
I am pretty newbie as you can see. At the first i thought as a double pointer but clearly it isn't. I can only use the ”iostream” header file and the Matrix class’ interface header file that which is given to me.
Look in the following link, its pretty self-explanatory, and will guide your implementation (supposing you know how to do it without templates):
http://www.cplusplus.com/doc/tutorial/templates/#class_templates
You will end initializing your class as:
Matrix<int> *myMatrix = new Matrix<int>(data, 10,10);
or
Matrix<int> myMatrix(10,10);
Matrix::Matrix(int numRows = 0, int numCols = 0)
:data(new T[numRows][numCols]){}
Matrix::~Matrix(){delete [] data;}
I'd let yourself figure out the rest.
In visual studio _CrtDumpMemoryLeaks() has detected memory leaks! But I could not find how it is happening. Please tell me what is wrong with the following code.?
// Declaration
template <class T> class cMatrix {
private:
std::vector<std::vector<T> > mat;
unsigned rows;
unsigned cols;
public:
cMatrix(unsigned _rows, unsigned _cols, const T& _initial);
cMatrix(const cMatrix<T>& rhs);
virtual ~cMatrix();
}
//Constructor
template<class T>
cMatrix<T>::cMatrix(unsigned _rows, unsigned _cols, const T& _initial) {
mat.resize(_rows);
for (unsigned i=0; i<mat.size(); i++) {
mat[i].resize(_cols, _initial);
}
rows = _rows;
cols = _cols;
}
//VirtualDestructor
template<class T>
cMatrix<T>::~cMatrix() {}
mat1 and mat4 can be destroyed after CrtDumpMemoryLeaks() call, move declaration of variable to own block.
int main()
{
{
cMatrix<double> mat1(2, 3, 23.0), mat4(2, 3, 15.0);
}
CrtDumpMemoryLeaks();
return 0;
}
Problem is that _CrtDumpMemoryLeaks(); is called in the same scope as vector is, so object does not get destroyed when it is called.
This won't show any memory leaks:
int main()
{
{
cMatrix<double> mat1(2, 3, 23.0), mat4(2, 3, 15.0);
}
_CrtDumpMemoryLeaks();
}
By the way, more efficient way to define cMatrix would be
// Declaration
template <class T> class cMatrix {
private:
std::vector<std::vector<T> > mat;
unsigned rows;
unsigned cols;
public:
cMatrix(unsigned _rows, unsigned _cols, const T& _initial);
virtual ~cMatrix();
};
//Constructor
template<class T>
cMatrix<T>::cMatrix(unsigned _rows, unsigned _cols, const T& _initial)
: mat(_rows,std::vector<T>(_cols,_initial))
, rows(_rows)
, cols(_cols)
{
}
//VirtualDestructor
template<class T>
cMatrix<T>::~cMatrix() {}
You've gotten some advice giving one possible way to deal with the problem you've seen. At least IMO, there's a somewhat better way though. Instead of mixing the diagnostic code with the other code, then adding braces to introduce a scope that's irrelevant to the real code, I'd separate the leak-dumping code even more completely, by putting it into a separate class:
struct leak_dumper {
~leak_dumper() { _CrtDumpMemoryLeaks(); }
} dump_leaks_at_exit;
This creates a global instance of the object, so you can simply add these three lines of code to the same file that contains your main (or WinMain) and it'll do the leak-dumping after main exits (with no other modification of your existing code).
As far as how to define a 2D matrix goes: a vector of vectors generally makes sense only if different rows of the matrix might contain different numbers of columns. If you want a rectangular matrix, you're generally better off with a single vector, and converting 2D coordinates to one dimension in an overloaded operator.
template <class T>
class matrix2D {
std::vector<T> data;
int columns;
public:
T &operator()(int x, int y) {
return data[y * columns + x];
}
matrix2D(int x, int y) : data(x*y), columns(x) {}
};
This reduces the total memory you use and, perhaps more importantly, keeps the data contiguous instead of allocating the data for each row separately.
I'm trying to perform a strided access to a submatrix with a single index. I need this for a library I'm working on which uses expression templates. I have worked out the following class, where the access is performed by the overloaded operator[], see below:
template <class A, class Type>
class SubMatrixExpr
{
private:
int Rows_; // Rows of the SubMatrix
int Columns_; // Columns of the SubMatrix
int Rows_up_; // Rows of the original Matrix
int Columns_up_; // Columns of the original Matrix
int a_, c_; // Starting indices of the SubMatrix as evaluated in the original Matrix
int rowstep_, columnstep_; // Stride along rows and columns for the original matrix
A M_;
public:
SubMatrixExpr(A &M, int Rows_up, int Columns_up, int Rows, int Columns, int a, int rowstep, int c, int columnstep) :
a_(a), c_(c), M_(M),
Rows_(Rows),
Columns_(Columns),
Rows_up_(Rows_up), Columns_up_(Columns_up),
rowstep_(rowstep), columnstep_(columnstep) { }
inline const Type& operator[](const int i) const
{
const int LocalRow = i/Columns_;
const int LocalColumn = i%Columns_;
const int GlobalRow = a_+rowstep_*LocalRow;
const int GlobalColumn = c_+columnstep_*LocalColumn;
return M_[IDX2R(GlobalRow,GlobalColumn,Columns_up_)];
}
inline Type& operator[](const int i)
{
// Similar to above
}
};
where
#define IDX2R(i,j,N) (((i)*(N))+(j))
The overloaded operator[] works correctly, but is computationally very expensive.
Is there any way to better implement the overloaded operator[]?
Thanks a lot in advance.
The only way you may got speedup is if you now the size of the matrices and sub-matrices at compile time. Then using template / constexpr may speedup things. For example if the size is known to be a power of 2 at compile time, the compiler will be able to replace division by shift.
I need a Matrix class for a project I'm doing in C++ but I don't know how to declare the constructor.
I know I need a height and a width. But how do I go about the part where I store the values? What's the best practice?
I thought about having my constructor be:
Matrix::Matrix(int height, int width, int[] values)
and so the private attributes of my class would be height, width and? How can I say that I want to store a number of values that I don't have yet?
I hope this makes sense... I'm finding it very hard to explain and that's probably because I'm very confuse. I'm very new with C++, so any extra help will be appreciated.
Just for an illustration list of constructors for OpenCV's cv::Mat class:
// constructors
Mat();
// constructs matrix of the specified size and type
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
Mat(int _rows, int _cols, int _type);
Mat(Size _size, int _type);
// constucts matrix and fills it with the specified value _s.
Mat(int _rows, int _cols, int _type, const Scalar& _s);
Mat(Size _size, int _type, const Scalar& _s);
// copy constructor
Mat(const Mat& m);
// constructor for matrix headers pointing to user-allocated data
Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP);
Mat(Size _size, int _type, void* _data, size_t _step=AUTO_STEP);
// creates a matrix header for a part of the bigger matrix
Mat(const Mat& m, const Range& rowRange, const Range& colRange);
Mat(const Mat& m, const Rect& roi);
// converts old-style CvMat to the new matrix; the data is not copied by default
Mat(const CvMat* m, bool copyData=false);
// converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false);
// builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
// helper constructor to compile matrix expressions
Mat(const MatExpr_Base& expr);
// assignment operators
Mat& operator = (const Mat& m);
Mat& operator = (const MatExpr_Base& expr);
I think this is good place to get inspiration or use it for your project, hover I'd recommend following constructors:
// Will declare whether to fill allocated data with zeros, ones or leave it be
enum MatrixFill { NO_INITIALIZATION, ZERO_FILL, ONES_FILL};
Matrix( const int width, const int height, const MatrixFill fill = NO_INITIALIZATION);
// To initialize from T data[] = {1,2,3,1,2,3,1,2,3};
Matrix( const int width, const int height, const T *data);
// To initialize from T data[][3] = {{1,2,3},{1,2,3},{1,2,3}};
Matrix( const int width, const int height, const T **data);
// To initialize from other matrix
Matrix( const Matrix &orig);
// Don't forget assign operator
Matrix &operator=(const Matrix &orig);
I'd also create type SubMatrix which wouldn't contain any data just link to parent data and range which would allow you to do this:
Matrix my( old.getSubMatrix( row, col, rowsCount, colsCount));
// And of course it'd have constructor like this:
Matrix( const SubMatrix &orig);
You may add many more constructors but I'd start with those five. Ask questions if you have any.
I'd learn from the pros: http://www.boost.org/doc/libs/1_48_0/libs/numeric/ublas/doc/matrix.htm#matrix
You should probably have a number of constructors, based on how you expect to use the class.
Assuming you plan to use Matrix for some kind of linear algebra, you should have a constructor which initializes the elements to zero:
Matrix(int height, int width); // initializes elements to 0
You should have constructors that initialize the elements from whatever data source you expect to find convenient (below, the type T is the element type of your Matrix):
Matrix(int height, int width, const std::vector<T> &data); // init from vector
Matrix(int height, int width, const T *data); // init from array
If you want to be able to declare an array of matrices, you need a default constructor:
Matrix(); // uninitialized or default array (to be initialized later)
You should also either define or disable copy constructors and assignment operators (or C++ will define them for you, badly):
Matrix(const Matrix &orig); // copy constructor
Matrix& operator=(const Matrix &orig); // assignment operator
I would really try to look for a book about OO design and their application in C++. As this question (besides hard to understand) shows a general misunderstanding of how object oriented languages work. I could explain it here in this topic; but that would be redundant and book authors can do it much better than me.
Basically what I understood from this question is that you know the sizes of your matrix, yet don't know the values they will get when you create them?
In that case simply make a constructor with only the sizes. And initialize the matrix to some "NULL" value. (Possibly even set a private member to false, indicating it isn't completely usable yet). The class and constructor would look like:
class Matrix() {
public:
Matrix(int nRows, int nColumns);
private:
int numRows;
int numColums;
std::vector<VALUE_TYPE> val;
};
Matrix::Matrix(int nRows, int nColums) {
int numRows = nRows;
int numColumns = nColums;
std::vector<VALUE_TYPE> val(nRows * nColums);
}
Simply said: the constructor only makes sure the memory is "allocated". Then you use other functions to fill in the actual values.
If you wish to provide "something", where you don't know exactly what "something" is. But you do know it is a container of data - you should use standard iterators (or templates). This is the manner how c++ handles inserting of data to standard containers. The function would be like this:
template <typename InIt>
Matrix::Matrix(int nRows, int nColums, InIt begin, InIt end) {
int numRows = nRows;
int numColumns = nColums;
//[begin, end) now holds the data - manipulate it at will.
std::vector<VALUE_TYPE> val(begin, end);
val.resize(nColums * nRows);
}
But once again: I'd take a book as the question to me seems unclear and answered by books.
Not strictly related to cpstructors but ... are you matrix expected to be resized during their life? If not, consider the idea not to have numRows and numCols as "variables" (they will never vary) but as template parameters.
Your matrix can be so declared as
Matrix<int,3,3> a; //a 3x3 integers
Matrix<double,3,2> a; //a 3x2 doubles
This will let impossible operations (like adding matrix with different sizes) impossible to compile.