TriangulatePoints and vector<Point2f> or CV_XXFC2 Matrices (Bug #2167)


Added by Simone Gasparini over 12 years ago. Updated over 12 years ago.


Status:Done Start date:2012-07-12
Priority:Normal Due date:
Assignee:Maria Dimashova % Done:

0%

Category:calibration, 3d
Target version:2.4.3
Affected version: Operating System:
Difficulty: HW Platform:
Pull request:

Description

I noticed that triangulatePoints does not work if used with vector<Point2f> or CV_XXFC2 matrices as input. This is because the underlying C function cvTriangulatePoints only works with points placed in 2xN matrices, while triangulatePoints uses the new way with InputArray, which usually means that everything is converted to a matrix of 2 channels (for 2D data)

So either cvTriangulate has to be changed to deal with the m-channel matrices or (more simply) we need to reshape the matrices before passing them to cvTriangulatePoints.

I don't know if it's the better way to do it but maybe at line 432 of triangulate.cpp we should put

Mat points1 = _projPoints1.getMat().reshape(1,2), points2 = _projPoints2.getMat().reshape(1,2);

so that the matrices passed to cvTriangulate are in the proper format.


testbug.cpp (751 Bytes) Simone Gasparini, 2012-07-15 11:47 pm


Associated revisions

Revision 33eef9cc
Added by Maria Dimashova over 12 years ago

fixed #2167

git-svn-id: file://localhost/home/tolik/svnrepo/trunk@9047 c5418bc3-7546-4aae-8bad-fa6f2f3e53e6

Revision d65920d2
Added by Maria Dimashova over 12 years ago

fixed #2167

Revision 25446b56
Added by Maria Dimashova over 12 years ago

revert my incorrect fix of #2167

git-svn-id: file://localhost/home/tolik/svnrepo/trunk@9049 c5418bc3-7546-4aae-8bad-fa6f2f3e53e6

Revision 5112d74c
Added by Maria Dimashova over 12 years ago

revert my incorrect fix of #2167

Revision bdc4af83
Added by Maria Dimashova over 12 years ago

fixed #2167

git-svn-id: file://localhost/home/tolik/svnrepo/trunk@9050 c5418bc3-7546-4aae-8bad-fa6f2f3e53e6

Revision 839761fa
Added by Maria Dimashova over 12 years ago

fixed #2167

Revision a39cf2dd
Added by Maria Dimashova over 12 years ago

updated doc on triangulatePoints (#2167)

Revision 801d2d0a
Added by Andrey Pavlenko about 11 years ago

Merge pull request #2167 from ilya-lavrenov:tapi_kern_warn

History

Updated by Simone Gasparini over 12 years ago

Sorry, it seems that the solution is a bit more complicated than that.
In order to convert a vector<Point2f> P into a single-channel matrix 2xN we have to do this

Mat(P).reshape( 1, P.size() ).t()

So a rough patch may be something like this

Mat points1 = _projPoints1.getMat(), points2 = _projPoints2.getMat();
int npts1 = points1.checkVector(2);
int npts2 = points2.checkVector(2);
CV_Assert( npts1 == npts2 && npts1 > 0);
points1 = points1.reshape( 1, npts1 ).t();
points2 = points2.reshape( 1, npts2 ).t();

But I'm sure you guys have a smarter and better way to do that :)

S.

Updated by Maria Dimashova over 12 years ago

Thanks! Fixed in r9047.

  • Status changed from Open to Done
  • Assignee set to Maria Dimashova

Updated by Simone Gasparini over 12 years ago

Sorry I gave you the wrong line number, line 432 belongs to the correctMatches, the correct line is 416.

Also, as i wrote in the update of this bug .reshape(1,2) is not correct, the output matrix shape will be correct (2xN) but the data inside it won't, because the points will be now in this format

[x0 y0 x1 y2... x(N/2) y(N/2);
x(N/2 + 1) y(N/2 + 1) .... x(N) y(N)]

Here is what i had proposed instead

Mat points1 = _projPoints1.getMat(), points2 = _projPoints2.getMat();
int npts1 = points1.checkVector(2);
int npts2 = points2.checkVector(2);
CV_Assert( npts1 == npts2 && npts1 > 0);
points1 = points1.reshape( 1, npts1 ).t();
points2 = points2.reshape( 1, npts2 ).t();

instead of

[x0 x1... x(N);
y0 y1 ....  y(N)]

I'm really sorry for the wrong reference for the line number :(

PS
I attach a sample of the code showing the conversion problem.

  • File testbug.cpp added

Updated by Maria Dimashova over 12 years ago

Thanks again! It's also my fault. I had to be more careful. Fixed in 839761fa.

Updated by Ilya Lysenkov over 12 years ago

Documentation should be updated too.

  • Status changed from Done to Open

Updated by Maria Dimashova over 12 years ago

Updated in a39cf2dd.

  • Status changed from Open to Done

Updated by Andrey Kamaev over 12 years ago

  • Target version set to 2.4.3

Updated by Pavel Gurevich over 12 years ago

Updated from the trunk yesterday, but still see wrong behavior of reshape(). The number of channels does not change under any condition via reshape().

#include <opencv2/core/core.hpp>
#include <iostream>
#include <vector>

using namespace std;
using namespace cv;

void print_size( const Mat& k ) {
   cout << k.size( ).width << "x" << k.size( ).height << "@" << k.channels( )
            << endl;
}

template < typename T >
void show_mat( const Mat& k ) {
   print_size( k );
   for ( int j = 0; j < k.size( ).height; ++ j ) {
      for ( int i = 0; i < k.size( ).width; ++ i )
         cout << k.at < T > ( j, i ) << ' ';
      cout << endl;
   }
}

int main( int argc, char *argv[ ] ) {
   vector < Point2f > pts;
   pts.push_back( Point2f( 1, 2 ) );
   pts.push_back( Point2f( 3, 4 ) );

   Mat m( pts );
   show_mat < float >( m );
   Mat m2;
   m.copyTo( m2 );
   m2.reshape( 1 );
   show_mat < float >( m2 );

   Mat m3;
   m.copyTo( m3 );
   m3.reshape( 1, m.size( ).area( ) * m.channels( ) );
   show_mat < float >( m3 );

   return 0;
}

Output:
-------
*

1x2@2
1 
3 
1x2@2
1 
3 
1x2@2
1 
3
*

Also available in: Atom PDF