PointCloudVisualizationModel.cpp
Go to the documentation of this file.
00001 
00033 #include "VisualizationModel.h"
00034 #include "PointCloudVisualizationModel.h"
00035 #include <cv.h>
00036 #include <string>
00037 #include <vector>
00038 
00039 #include "DVision.h"
00040 
00041 typedef DVision::PMVS::PLYFile PLYFile;
00042 typedef DVision::PMVS::PLYFile::PLYPoint PLYPoint;
00043 
00044 using namespace std;
00045 
00046 // ---------------------------------------------------------------------------
00047 
00048 PointCloudVisualizationModel::PointCloudVisualizationModel
00049   (const std::string &filename)
00050 {
00051   PLYFile::readFile(filename, m_plypoints);
00052   convertPLY2Mat();
00053   calculateDimensions();
00054 }
00055 
00056 // ---------------------------------------------------------------------------
00057 
00058 void PointCloudVisualizationModel::convertPLY2Mat()
00059 {
00060   m_oP.create(4, m_plypoints.size(), CV_64F);
00061   
00062   double *px = m_oP.ptr<double>(0);
00063   double *py = m_oP.ptr<double>(1);
00064   double *pz = m_oP.ptr<double>(2);
00065   double *ps = m_oP.ptr<double>(3);
00066   
00067   vector<PLYPoint>::const_iterator pit;
00068   for(pit = m_plypoints.begin(); pit != m_plypoints.end(); 
00069     ++pit, ++px, ++py, ++pz, ++ps)
00070   {
00071     *px = pit->x;
00072     *py = pit->y;
00073     *pz = pit->z;
00074     *ps = 1;
00075   }
00076 }
00077 
00078 // ---------------------------------------------------------------------------
00079 
00080 void PointCloudVisualizationModel::calculateDimensions()
00081 {
00082   if(m_plypoints.empty())
00083   {
00084     m_dimx = m_dimy = m_dimz = 0;
00085   }else
00086   {
00087     const double *px = m_oP.ptr<double>(0);
00088     const double *py = m_oP.ptr<double>(1);
00089     const double *pz = m_oP.ptr<double>(2);
00090     const int N = m_oP.cols;
00091     
00092     double minx = *std::min_element(px, px + N);
00093     double miny = *std::min_element(py, py + N);
00094     double minz = *std::min_element(pz, pz + N);
00095     
00096     double maxx = *std::max_element(px, px + N);
00097     double maxy = *std::max_element(py, py + N);
00098     double maxz = *std::max_element(pz, pz + N);
00099     
00100     m_dimx = maxx - minx;
00101     m_dimy = maxy - miny;
00102     m_dimz = maxz - minz;
00103   }
00104 }
00105 
00106 // ---------------------------------------------------------------------------
00107 
00108 void PointCloudVisualizationModel::draw(cv::Mat &img, const cv::Mat &_cTo,
00109   const cv::Mat &A, const cv::Mat &K) const
00110 {  
00111   cv::Mat k;
00112   if(K.empty())
00113     k = cv::Mat::zeros(4, 1, A.type());
00114   else
00115     k = K;
00116   
00117   cv::Mat cTo;
00118   if(_cTo.type() == CV_64F)
00119     cTo = _cTo;
00120   else
00121     _cTo.convertTo(cTo, CV_64F);
00122   
00123   cv::Mat cP = cTo * m_oP;
00124   
00125   vector<pair<double, int> > depths; // <z, point index>
00126   depths.reserve(cP.cols);
00127   
00128   if(cTo.at<double>(3,3) != 1)
00129   {
00130     // normalize 
00131     double *px = cP.ptr<double>(0);
00132     double *py = cP.ptr<double>(1);
00133     double *pz = cP.ptr<double>(2);
00134     double *ps = cP.ptr<double>(3);
00135     for(int i = 0; i < cP.cols; ++i, ++px, ++py, ++pz, ++ps)
00136     {
00137       *px /= *ps;
00138       *py /= *ps;
00139       *pz /= *ps;
00140       *ps = 1;
00141       
00142       depths.push_back(make_pair(*pz, i));
00143     }
00144   }
00145   
00146   if(depths.empty())
00147   {
00148     double *pz = cP.ptr<double>(2);
00149     for(int i = 0; i < cP.cols; ++i, ++pz)
00150     {
00151       depths.push_back(make_pair(*pz, i));
00152     }
00153   }
00154   
00155   // sort in ascending z
00156   sort(depths.begin(), depths.end());
00157   
00158   // project now to 2d
00159   vector<cv::Point2f> points2d;
00160   
00161   cv::Mat cP_Nx3;
00162   cP.convertTo(cP_Nx3, CV_32F);
00163   cP_Nx3 = cP_Nx3.rowRange(0,3).t();
00164   
00165   cv::projectPoints(cP_Nx3, 
00166     cv::Mat::eye(3,3,CV_64F), cv::Mat::zeros(3,1,CV_64F),
00167     A, k, points2d);
00168   
00169   // draw the further points first
00170   bool frame_painted = false;
00171   vector<pair<double, int> >::const_reverse_iterator pit;
00172   for(pit = depths.rbegin(); pit != depths.rend(); ++pit)
00173   {
00174     int pidx = pit->second;
00175     const PLYPoint& pp = m_plypoints[pidx];
00176     const cv::Point2f p2 = points2d[pidx];
00177     
00178     if(!frame_painted && pp.z > 0)
00179     {
00180       // time to paint the reference system
00181       frame_painted = true;
00182       
00183       // draw a reference system
00184       float length;
00185       float d[3] = {m_dimx, m_dimy, m_dimz};
00186       sort(d, d+3); // ascending
00187 
00188       if(d[0] < d[2]/3.f)
00189       {
00190         // thin object
00191         length = 0.5f * d[1];
00192       }
00193       else
00194       {
00195         // almost a cube
00196         length = 0.5f * d[0];
00197       }
00198     }
00199     
00200     CvScalar c = cvScalar(pp.b, pp.g, pp.r);
00201     cv::circle(img, cvPoint(p2.x, p2.y), 0, c);
00202     cv::circle(img, cvPoint(p2.x, p2.y), 1, c);
00203   }
00204 
00205 }
00206 
00207 // ---------------------------------------------------------------------------
00208 
00209 


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:09