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;
00126 depths.reserve(cP.cols);
00127
00128 if(cTo.at<double>(3,3) != 1)
00129 {
00130
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
00156 sort(depths.begin(), depths.end());
00157
00158
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
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
00181 frame_painted = true;
00182
00183
00184 float length;
00185 float d[3] = {m_dimx, m_dimy, m_dimz};
00186 sort(d, d+3);
00187
00188 if(d[0] < d[2]/3.f)
00189 {
00190
00191 length = 0.5f * d[1];
00192 }
00193 else
00194 {
00195
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