Integers to Matrix (cvMat) - c++

Hey guys,
I'm working on a project. I need to use the function cvFindHomography in openCV before this step I have applied LK optical flow function, so I get the features in the first frame and in the second frame as INTEGERS, well in cvFindHomography I need to use these features but as cvMat not as integers.
Do you have any I idea how to put these integers in a Matrix in order to use them in the function mentioned above.
Thank you.

You can use the cvMat() constructor:
CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))

Related

How to make getting a pixel value independent of the cv::Mat type?

I am writing a method that uses OpenCV (C++).
For example
void foo(const cv::Mat &image);
Inside, I need to take the pixel value of the cv::Mat by row and column.
If the type of image the method works with is CV_32FC3, I need to use
image.at<cv::Vec3f>(row, col);
If the type is CV_32SC2, I need to use
image.at<cv::Vec2i>(row, col);
If the type is CV_8UC1, I need to use
image.at<uchar>(row, col);
etc.
I would like the method to be universal, that is, it works with an image with any number of channels and depth. Can anything be done to fulfill this requirement (any template logic)? Perhaps the solution is quite obvious, but I did not find it.
Thank you!
Drop the use of cv::Mat - where you have to call type() method (at runtime) to get the type of values stored by mat, and instead that just start using templated version of mat class: it is cv::Mat_<Type> and write more generic code.
Then you could write only one function template to read mat pixels:
template<class T>
T access(cv::Mat_<T> const& img, int r, int c) {
return img(r,c);
}
More about cv::Mat_ here.

Fitting 2d gauss function in C++ too slow

I'm trying to fit a 2d gauss function to an image (in cv::Mat format), and I'm using the NLopt library.
I put my object function like this:
for(i for each row)
for(j for each col)
{
//compute the gauss function value
double valuenow=x[0]*exp(-( x[3]*(j-x[1])*(j-x[1]) + 2*x[4]*(j-x[1])*(i-x[2]) + x[5]*(i-x[2])*(i-x[2]) ));
//add square residual to result
result+=(valuenow-fitdata.at<double>(i,j))*(valuenow-fitdata.at<double>(i,j));
}
return result;
My matrix is about 1000*1000 size, I'm using LN_COBYLA algorithm. When I ran this, it turned out to be extremely slow. I think there must be something wrong with the way I specify my object function, because I used to do the same thing in Matlab with lsqnonlinear, which returned in a second.
Can someone help me please? Thanks in advance.
The at<>() function is slow. If speed is of essence, it's not a good idea to use it inside loops. Take a pointer outside the loop and then just use that pointer inside the loop.
A related question:
OpenCV Mat array access, which way is the fastest for and why?

how can set a pointer to the content of a Mat variable in OpenCV

A Mat can be CV_8UC3, CV_8UC1, CV_32FC3 and etc. For example, for a Mat which is CV_8UC3, I can set a pointer: Vec3b *p to the Mat. However, If I only know the Mat's datatype which can be obtained using Mat.type(), How can I set a proper pointer?
The sad answer is: you can't. The type of data should be set in compilation time. But in your example actual type will be decided only during run time. You will have to put switch somewhere in your code. i.e. you will need to have different implementations of your algorithm for all possible types. Note however that you can prevent code duplication by using templates.
If you do know type of data, and the only thing you don't know is number of channels, then the problem is a bit simpler. For example if your image contains unsigned char you can write
uchar* p = img.ptr<uchar>();
And it doesn't matter whether your image have one channel or three. Of course when it comes to actually working with the pixels you do need this information.
Use a void pointer. Void pointers can point to any data type.
http://www.learncpp.com/cpp-tutorial/613-void-pointers/
If you know a type, you can set a pointer to the first element of the first row of cv::Mat using ptr (documentation)
cv::Mat matrix = cv::Mat::zeros(3, 3, CV_32F);
float* firstElement = matrix.ptr<float>(0);

OpenCV Add columns to a matrix

in OpenCV 2 and later there is method Mat::resize that let's you add any number of rows with the default value to your matrix is there any equivalent method for the column. and if not what is the most efficient way to do this.
Thanks
Use cv::hconcat:
Mat mat;
Mat cols;
cv::hconcat(mat, cols, mat);
Worst case scenario: rotate the image by 90 degrees and use Mat::resize(), making columns become rows.
Since OpenCV, stores elements of matrix rows sequentially one after another there is no direct method to increase column size but I bring up myself two solutions for the above matter,
First using the following method (the order of copying elements is less than other methods), also you could use a similar method if you want to insert some rows or columns not specifically at the end of matrices.
void resizeCol(Mat& m, size_t sz, const Scalar& s)
{
Mat tm(m.rows, m.cols + sz, m.type());
tm.setTo(s);
m.copyTo(tm(Rect(Point(0, 0), m.size())));
m = tm;
}
And the other one if you are insisting not to include even copying data order into your algorithms then it is better to create your matrix with the big number of rows and columns and start the algorithm with the smaller submatrix then increase your matrix size by Mat::adjustROI method.

Need to keep track of types of opencv Mats

So I'm using the class Mat from opencv in a program I'm writing. Mat looks something like this:
class Mat {
public:
Mat(int width, int height, int type);
template <typename T> T getElt(int x, int y);
int depth();
...
}
The type in the constructor specifies whether elements in the Mat are floats, ints, etc as well as the number of channels in the image. depth() returns the data type used to store image elements.
Unfortunately I have to call getElt() in my code. Whenever I do that I use a switch statement to check the depth of the Mat so I can call getElt() with the appropriate template parameter. Doing it that way is pretty verbose, so I was wondering if there was a better way to do it. Could I create a container for a Mat and use template magic create a method that returns a type as opposed to a value? Or could I use macros to make things more efficient and logical?
I'd rather not have to subclass Mat since there are several methods besides getElt() for which I have this same issue.
Edit: made the description more accurate.
You're probably looking for Mat_<T> instead. An black&white image really isn't the same as a greyscale image, and neither is equal to a color image. Those should be separate at compile time.
IIRC the 'type' in openCV MAT corresponds to the image type (ie number of channels) not the data type float/int/char etc.
If you want a templated image class that can transparently work with char/int/bool/double etc - take a look at CImg