PlanePatch.cpp
Go to the documentation of this file.
00001 #include <structureColoring/structures/PlanePatch.h>
00002 #include <limits.h>
00003 #include <assert.h>
00004 
00005 /*****************************************************************************/
00006 
00007 PlanePatch::PlanePatch(const Vec3& normal, const float distance, const float distanceThreshold, const Points& brVertices,
00008                 const float texWidthRatio, const float texHeightRatio, const cv::Mat& heightMap, const cv::Mat& textureMap)
00009                 : mPlane(normal, distance), mBRVertices(brVertices), mTextureMap(cv::Mat(textureMap)), mHeightMap(cv::Mat(heightMap)),
00010                   mTextureWidthRatio(texWidthRatio), mTextureHeightRatio(texHeightRatio), mDistanceThreshold(distanceThreshold){
00011         computeNormalMap();
00012 }
00013 
00014 /*****************************************************************************/
00015 
00016 //PlanePatch::~PlanePatch() {
00017 //}
00018 
00019 /*****************************************************************************/
00020 
00021 void PlanePatch::getLimitsXY(float& xMin, float& xMax, float& yMin, float& yMax) const {
00022         xMin = mXMin;
00023         xMax = mXMax;
00024         yMin = mYMin;
00025         yMax = mYMax;
00026 }
00027 
00028 /*****************************************************************************/
00029 
00030 void PlanePatch::newGrid(const float cellSize) {
00031         mGrid.reset(new GridMap(mPlane, mXMin, mXMax, mYMin, mYMax, cellSize));
00032 }
00033 
00034 /*****************************************************************************/
00035 
00036 void PlanePatch::computeTextureSize(float& texPixSize, unsigned int& wPot, unsigned int& hPot, const float texelSizeFactor) {
00037         float xSpan = fabs(mXMax - mXMin);
00038         float ySpan = fabs(mYMax - mYMin);
00039         texPixSize = texelSizeFactor * std::sqrt(xSpan * ySpan / mInlierIndices.size());
00040         unsigned int width = (xSpan / texPixSize) + 1;
00041         unsigned int height = (ySpan / texPixSize) + 1;
00042         compute2PotTexSize(mTextureWidthRatio, mTextureHeightRatio, wPot, hPot, width, height);
00043 }
00044 
00045 /*****************************************************************************/
00046 
00047 void PlanePatch::compute2PotTexSize(float& widthRatio, float& heightRatio, unsigned int& wPot, unsigned int& hPot,
00048                 const unsigned int width, const unsigned int height){
00049         wPot = 2;
00050         hPot = 2;
00051         while (wPot < width)
00052                 wPot *= 2;
00053         while (hPot < height)
00054                 hPot *= 2;
00055         widthRatio = (float) width / (float) wPot;
00056         heightRatio = (float) height / (float) hPot;
00057 }
00058 
00059 
00060 /*****************************************************************************/
00061 
00062 void PlanePatch::computeRGBTextureMap(const ColoredPointCloud& pointCloud, const float texelSizeFactor,
00063                 const unsigned int dilateIterations) {
00064         union {
00065                 float rgbfloat;
00066                 uint32_t rgbint;
00067         } ColorUnion;
00068         float texPixSize = 0.f;
00069         unsigned int wPot = 0, hPot = 0;
00070         computeTextureSize(texPixSize, wPot, hPot, texelSizeFactor);
00071         mTextureMap = cv::Mat::zeros(hPot, wPot, CV_32FC4);
00072         cv::Mat texCounter(cv::Mat::zeros(hPot, wPot, CV_8UC1));
00073         for (PointIndices::const_iterator point_it = mInlierIndices.begin(); point_it != mInlierIndices.end(); ++point_it) {
00074                 ColorUnion.rgbfloat = pointCloud.points[*point_it].rgb;
00075                 int rgb = ColorUnion.rgbint;
00076                 Vec3 p = mPlane.transformToXYPlane(pointCloud.points[*point_it].getVector3fMap());//this does not store the projected points to mPoints
00077                 unsigned int x = fabs(p[0] - mXMin) / texPixSize;
00078                 unsigned int y = fabs(p[1] - mYMin) / texPixSize;
00079                 mTextureMap.at<cv::Vec4f> (y, x)[0] += (float) ((rgb >> 16) & 0xff) / (float) 255;
00080                 mTextureMap.at<cv::Vec4f> (y, x)[1] += (float) ((rgb >> 8) & 0xff) / (float) 255;
00081                 mTextureMap.at<cv::Vec4f> (y, x)[2] += (float) (rgb & 0xff) / (float) 255;
00082                 mTextureMap.at<cv::Vec4f> (y, x)[3] = 1.f;
00083                 texCounter.at<char> (y, x) += 1;
00084         }
00085         for (unsigned int hind = 0; hind < hPot; ++hind) {
00086                 for (unsigned int wind = 0; wind < wPot; ++wind) {
00087                         char count = texCounter.at<char> (hind, wind);
00088                         if (count != 0) {
00089                                 mTextureMap.at<cv::Vec4f> (hind, wind)[0] /= (float) count;
00090                                 mTextureMap.at<cv::Vec4f> (hind, wind)[1] /= (float) count;
00091                                 mTextureMap.at<cv::Vec4f> (hind, wind)[2] /= (float) count;
00092                         }
00093                 }
00094         }
00095         if (dilateIterations)
00096                 cv::dilate(mTextureMap, mTextureMap, cv::Mat(), cv::Point(-1, -1), dilateIterations);
00097         //      cv::GaussianBlur(*mTextureMap, *mTextureMap, cv::Size(3,3), 2, 2);
00098         computeHeightMap(texPixSize, pointCloud, dilateIterations);
00099         printf("texture and heightmap computed with true size of (%u, %u) = %u pixels", (unsigned int)(wPot * mTextureWidthRatio), (unsigned int)(hPot * mTextureHeightRatio), (unsigned int)((wPot * hPot * mTextureWidthRatio * mTextureHeightRatio) +0.5f));
00100         cv::Mat img;
00101         mTextureMap.convertTo(img, CV_8U, 255);
00102 }
00103 
00104 /*****************************************************************************/
00105 
00106 void PlanePatch::computeIntensityTextureMap(const IntensityPointCloud& pointCloud, const float texelSizeFactor,
00107                 const unsigned int dilateIterations) {
00108         float texPixSize = 0.f;
00109         unsigned int wPot = 0, hPot = 0;
00110         computeTextureSize(texPixSize, wPot, hPot, texelSizeFactor);
00111         mTextureMap = cv::Mat::zeros(hPot, wPot, CV_32FC2);
00112         cv::Mat texCounter(cv::Mat::zeros(hPot, wPot, CV_8UC1));
00113         for (PointIndices::const_iterator point_it = mInlierIndices.begin(); point_it != mInlierIndices.end(); ++point_it) {
00114                 Vec3 p = mPlane.transformToXYPlane(pointCloud.points[*point_it].getVector3fMap());//this does not store the projected points to mPoints
00115                 unsigned int x = fabs(p[0] - mXMin) / texPixSize;
00116                 unsigned int y = fabs(p[1] - mYMin) / texPixSize;
00117                 //TODO normalize intensity to 1 if this is not done before
00118                 mTextureMap.at<cv::Vec2f> (y, x)[0] = pointCloud.points[*point_it].intensity;//assuming that intensity is scaled to ranges 0 .. 1
00119                 mTextureMap.at<cv::Vec2f> (y, x)[1] = 1.f;
00120                 texCounter.at<char> (y, x) += 1;
00121         }
00122         for (unsigned int hind = 0; hind < hPot; ++hind) {
00123                 for (unsigned int wind = 0; wind < wPot; ++wind) {
00124                         char count = texCounter.at<char> (hind, wind);
00125                         if (count != 0) {
00126                                 mTextureMap.at<cv::Vec2f> (hind, wind)[0] /= (float) count;
00127                         }
00128                 }
00129         }
00130         if (dilateIterations)
00131                 cv::dilate(mTextureMap, mTextureMap, cv::Mat(), cv::Point(-1, -1), dilateIterations);
00132         //      cv::GaussianBlur(*mTextureMap, *mTextureMap, cv::Size(3,3), 2, 2);
00133         computeHeightMap(texPixSize, pointCloud, dilateIterations);
00134 }
00135 
00136 /*****************************************************************************/
00137 
00138 void PlanePatch::computeAlphaMap(const PointCloud& pointCloud, const float texelSizeFactor,
00139                 const unsigned int dilateIterations) {
00140         float texPixSize = 0.f;
00141         unsigned int wPot = 0, hPot = 0;
00142         computeTextureSize(texPixSize, wPot, hPot, texelSizeFactor);
00143         mTextureMap = cv::Mat::zeros(hPot, wPot, CV_8UC1);
00144         for (PointIndices::const_iterator point_it = mInlierIndices.begin(); point_it != mInlierIndices.end(); ++point_it) {
00145                 Vec3 p = mPlane.transformToXYPlane(pointCloud.points[*point_it].getVector3fMap());
00146                 unsigned int x = fabs(p[0] - mXMin) / texPixSize;
00147                 unsigned int y = fabs(p[1] - mYMin) / texPixSize;
00148                 mTextureMap.at<char> (y, x) = 255;
00149         }
00150         if (dilateIterations)
00151                 cv::dilate(mTextureMap, mTextureMap, cv::Mat(), cv::Point(-1, -1), dilateIterations);
00152         //      cv::GaussianBlur(*mTextureMap, *mTextureMap, cv::Size(3,3), 2, 2);
00153         computeHeightMap(texPixSize, pointCloud, dilateIterations);
00154 }
00155 
00156 /*****************************************************************************/
00157 //http://www.gamedev.net/topic/428776-create-a-normal-map-from-heightmap-in-a-pixel-shader/
00158 /*
00159 float val = tex2D(tx_Heightfield, PixelInput.TextureCoord0);
00160 float valU = tex2D(tx_Heightfield, PixelInput.TextureCoord0 + float2(1 / 512, 0));
00161 float valV = tex2D(tx_Heightfield, PixelInput.TextureCoord0 + float2(0, 1 / 512));
00162 float3 normal = normalize(float3(val - valU, 0.5, val - valV));
00163 */
00164 void PlanePatch::computeNormalMap() {
00165         unsigned int height = mHeightMap.rows;
00166         unsigned int width = mHeightMap.cols;
00167         mNormalMap = cv::Mat::zeros(height, width, CV_32FC3);
00168         for (unsigned int hind = 0; hind+1 < height; ++hind) {
00169                 for (unsigned int wind = 0; wind+1 < width; ++wind) {
00170                         float val = mHeightMap.at<float>(hind, wind);
00171                         float valU = mHeightMap.at<float>(hind+1, wind);
00172                         float valV = mHeightMap.at<float>(hind, wind+1);
00173                         Vec3 vec(val - valU, 0.3f, val-valV);
00174                         vec.normalize();
00175                         vec += Vec3(1.f, 1.f, 1.f);
00176                         vec *= 0.5f;
00177                         mNormalMap.at<cv::Vec3f> (hind, wind)[0] = vec.x();
00178                         mNormalMap.at<cv::Vec3f> (hind, wind)[1] = vec.y();
00179                         mNormalMap.at<cv::Vec3f> (hind, wind)[2] = vec.z();
00180                 }
00181         }
00182         cv::GaussianBlur(mNormalMap, mNormalMap, cv::Size(3, 3), 2, 2);
00183 }
00184 
00185 /*****************************************************************************/
00186 
00187 void PlanePatch::computeOrientedBoundingBox() {
00188         //set mBBVertices (vertices of BoundingBox)
00189         mBBVertices.clear();
00190         mBBVertices.push_back(Eigen::Vector3f(mXMin, mYMin, mZMin));
00191         mBBVertices.push_back(Eigen::Vector3f(mXMin, mYMax, mZMin));
00192         mBBVertices.push_back(Eigen::Vector3f(mXMax, mYMin, mZMin));
00193         mBBVertices.push_back(Eigen::Vector3f(mXMax, mYMax, mZMin));
00194         mBBVertices.push_back(Eigen::Vector3f(mXMax, mYMin, mZMax));
00195         mBBVertices.push_back(Eigen::Vector3f(mXMax, mYMax, mZMax));
00196         mBBVertices.push_back(Eigen::Vector3f(mXMin, mYMin, mZMax));
00197         mBBVertices.push_back(Eigen::Vector3f(mXMin, mYMax, mZMax));
00198         //transform from plane-coordinate system to "normal" xyz-coordinates
00199         for (unsigned int i = 0; i < mBBVertices.size(); i++) {
00200                 mBBVertices[i] = mPlane.transformToXYZCoords(mBBVertices[i]);
00201         }
00202 }
00203 
00204 /*****************************************************************************/
00205 
00206 void PlanePatch::computeBoundingRectangle() {
00207         //set mBRVertices (vertices of BoundingRectangle on plane)
00208         mBRVertices.clear();
00209         mBRVertices.push_back(Eigen::Vector3f(mXMin, mYMin, 0.f));
00210         mBRVertices.push_back(Eigen::Vector3f(mXMin, mYMax, 0.f));
00211         mBRVertices.push_back(Eigen::Vector3f(mXMax, mYMax, 0.f));
00212         mBRVertices.push_back(Eigen::Vector3f(mXMax, mYMin, 0.f));
00213         //transform from plane-coordinate system to "normal" xyz-coordinates
00214         for (unsigned int i = 0; i < mBRVertices.size(); i++) {
00215                 mBRVertices[i] = mPlane.transformToXYZCoords(mBRVertices[i]);
00216         }
00217 }
00218 
00219 /*****************************************************************************/
00220 
00221 bool PlanePatch::checkPointConnection(const Vec3& p, const int connectionNeighbors) const {
00222         return mGrid->checkPointConnection(p, connectionNeighbors);
00223 }
00224 
00225 /*****************************************************************************/
00226 
00227 float PlanePatch::distanceToOBB(const Vec3& p) const {
00228         const Eigen::Vector3f localP = mPlane.transformToXYPlane(p);
00229         float a = 0, b = 0, c = 0;
00230         if (localP.x() < mXMin)
00231                 a = mXMin - localP.x();
00232         else if (localP.x() > mXMax)
00233                 a = localP.x() - mXMax;
00234         if (localP.y() < mYMin)
00235                 b = mYMin - localP.y();
00236         else if (localP.y() > mYMax)
00237                 b = localP.y() - mYMax;
00238         if (localP.z() < mZMin)
00239                 c = mZMin - localP.z();
00240         else if (localP.z() > mZMax)
00241                 c = localP.z() - mZMax;
00242         return std::sqrt(a * a + b * b + c * c);
00243 }


structure_coloring_fkie
Author(s): Bastian Gaspers
autogenerated on Sun Jan 5 2014 11:38:09