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
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());
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
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());
00115 unsigned int x = fabs(p[0] - mXMin) / texPixSize;
00116 unsigned int y = fabs(p[1] - mYMin) / texPixSize;
00117
00118 mTextureMap.at<cv::Vec2f> (y, x)[0] = pointCloud.points[*point_it].intensity;
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
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
00153 computeHeightMap(texPixSize, pointCloud, dilateIterations);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
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
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
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
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
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 }