Reputation: 4191
My question might be sitting somewhere in Stackoverflow that I couldn't find, if so, could you give me link.
Basically, I want to write a method that can be used for all matrix types. My method is as follows:
Mat my_func(Mat in){
Mat out(in.rows, in.cols, in.type());
for(int i =0; i < x; i++)
for(int j =0; j < x; j++)
out.at<in.type()>(i,j) = in.at<in.type()>(j,i); //this is just an example,
//consider that I need to use
//out.at<in.type()>(i,j) part
}
out.at<in.type()>(i,j)
gives error as it doesn't accept <in.type>
, it requires <double>, <float>
etc.
I solved this problem by
if(in.type() == 5)
out.at<float>(i,j) = //do something for float
else if (in.type() == 6)
out.at<double>(i,j) = //do something for double
There should be a better way, but I couldn't find. I searched related to typedef
but I couldn't understand much from what I have found.
Note that: in.type() = 5
indicates that Matrix named in
is a mat of floats
, similarly 6
is mat of doubles
.
Thanks in advance,
Upvotes: 1
Views: 237
Reputation: 81
I wrote a function to write any type of mat to txtfile which can be read in matlab using matlab function 'dlmread'
int main()
{
Mat matDilate;
SaveToNotepad(matDilate,"C://matDilate.txt");
return 0;
}
template <class T>
void CFindObjectByThreshColorImage::PrintMat(T* image, int rows, int cols, std::string fileName)
{
try
{
ofstream fout(fileName);
if(fout.is_open())
{
for ( unsigned int i = 0; i < rows; i ++)
{
for (unsigned int j = 0; j < cols; j ++)
{
fout << image[i*cols+j]<<"\t"; // behaves like cout - cout is also a stream
//cerr<< image[i*cols+j]<<"\t";
}
fout << endl;
}
fout.close();
}
}
catch (exception& e)
{
LOG( ALG_LOGGER, Error, "CFindHoughCircle::file write Exception " + string(e.what()));
}
}
///////////////////////////////////////////////////////
>// SaveToNotepad
>//writes the mat to the destination fileName
>// Example :SaveToNotepad(diff_im,"C://diff_im.txt");
>//////////////////////////////////////////////////////
void CFindObjectByThreshColorImage::SaveToNotepad( Mat WriteMatrix, std::string fileName)
{
int iImgType = WriteMatrix.type();// finding which datat type it is
switch (iImgType)
{
case 0:
// "CV_8U";
PrintMat((uchar*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);//
break;
case 1:
// "CV_8S";
PrintMat(( char*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);
break;
case 2:
//"CV_16U";
PrintMat(( ushort*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);
break;
case 3:
// "CV_16S";
PrintMat(( short*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);
break;
case 4:
// "CV_32S";
PrintMat(( int*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);
break;
case 5:
// "CV_32F";
PrintMat(( float*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);
break;
case 6:
// "CV_64F";
PrintMat(( double*) WriteMatrix.data, WriteMatrix.rows , WriteMatrix.cols, fileName);
break;
default:
LOG( ALG_LOGGER, Error, "CFindHoughCircle:: Mat type Exception " + fileName);
break;
}
Upvotes: 0
Reputation: 39816
m.at<type>(i,j)
is a template expression. the compiler has to resolve the type at compile time.
so, any try to cheat at runtime like m1.at<m2.type()>(i,j)
is doomed.
the good news is , that there are template Mat's as well, like Mat_<float>
which you can access just like m(i,j)
( without the pesky template brackets ).
so, your example code might even look like:
template<class T>
Mat_<T> my_func(Mat_<T> in){
Mat_<T> out(in.cols, in.rows);
for(int i =0; i < in.cols; i++)
for(int j =0; j < in.rows; j++)
out(j,i) = in(i,j);
return out;
}
int main()
{
// called like :
Mat_<int> in;
Mat_<int> res = my_func(in);
return 0;
}
honestly, it's a very rare case, that you don't know your Mat's type at compile time, for those you'll still need code like if type==5 do_something, arrays of function pointers indexed by typeid or similar.
Upvotes: 4
Reputation: 120229
Better ways that come to mind:
Mat_<...>
instead of Mat
.at
and assignment, extract a 1×1 rectangle an use Mat::copyTo()
.case (Mat.type()) {...}
routine inside that function.Upvotes: 1