今天出了一个问题,隐藏了好几天,那就是在点云和tif文件读写时,坐标系出现了换算错误,是我代码的问题。
在笛卡儿坐标系中,X向右为正,y向上为正,而在tif文件中,用的图像坐标系,x向右为正,y向下为正,分辨率为负数,比如:
//设置X,Y方向的像素分辨率
double xResolution = 1.0;
double yResolution = -1.0;
//根据点云集求点云的细节
_theDetail = this->getPCLDetailFromDataSet();
//求X,Y方向的像素个数,
double xSizef = abs( _theDetail.xDistance / xResolution );
double ySizef = abs( _theDetail.yDistance / yResolution );
//取整
_xSize = (int)xSizef;
_ySize = (int)ySizef;
根据点云集,求点云的细节内容
PCLDetail PCLTif::getPCLDetailFromDataSet()
{
//判断输入集合的范围
//首先给定输入集合的X,Y坐标
pt3Set::iterator
iterInputExtentCur = _pointCloudDataSet.begin(),
iterInputExtentEnd = _pointCloudDataSet.end();
//判断XY的最小最大值,以此判定范围
iterInputExtentCur = _pointCloudDataSet.begin();
double minX = iterInputExtentCur->second.x();
double minY = iterInputExtentCur->second.y();
double maxX = iterInputExtentCur->second.x();
double maxY = iterInputExtentCur->second.y();
for (; iterInputExtentCur != iterInputExtentEnd; iterInputExtentCur++)
{
double x = iterInputExtentCur->second.x();
double y = iterInputExtentCur->second.y();
if (x < minX)
{
minX = x;
}
if (x > maxX)
{
maxX = x;
}
if (y < minY)
{
minY = y;
}
if (y > maxY)
{
maxY = y;
}
}
std::cout << "X的范围:(" << minX << "," << maxX << ")" << std::endl;
std::cout << "Y的范围:(" << minY << "," << maxY << ")" << std::endl;
//判断数据集的大小,
double distanceX = maxX - minX;
double distanceY = maxY - minY;
PCLDetail theDetail;
theDetail.leftTopX = minX;
theDetail.leftTopY = maxY; //注意,这里Y值,是左上角为最大值
theDetail.xDistance = distanceX;
theDetail.yDistance = distanceY;
return theDetail;
}
//根据输入集合求等分插值XYZ坐标
void PCLTif::getEqualXYZVectorFromDataSet()
{
_rasterVecVec.resize(_ySize);
//进行输入点云坐标三维坐标的输出
for (int i = 0; i < _ySize; i++)
{
std::vector<Pt3> imagePointVector3;
imagePointVector3.clear();
for (int j = 0; j < _xSize; j++)
{
double x = _theDetail.leftTopX + _xResolution * j;
double y = _theDetail.leftTopY + _yResolution * i; //注意这里是从上往下,y值逐渐减小
double z = -9999; //灰度值初值均为0
//double z = 0; //灰度值初值均为0
Pt3 thisPoint = Pt3(x, y, z);
imagePointVector3.push_back(thisPoint);
}
_rasterVecVec[i] = imagePointVector3;
}
}
//根据各个三角形计算出在该三角形外接矩形的栅格集合,插值
void PCLTif::getRasterVec3SetFromTriangle(std::vector<Pt3> theTrianglePt3)
{
//1,求该三角形的外接矩形
std::vector<Pt2> rectVec2 = this->_getRectanglePt2VectorFromTriangle(theTrianglePt3);
double minX = rectVec2[0].x();
double minY = rectVec2[0].y();
double maxX = rectVec2[3].x();
double maxY = rectVec2[3].y();
myRect theRect;
theRect.minX = minX;
theRect.minY = minY;
theRect.maxX = maxX;
theRect.maxY = maxY;
Vector3 vecA(theTrianglePt3[0].x(), theTrianglePt3[0].y(), 0);
Vector3 vecB(theTrianglePt3[1].x(), theTrianglePt3[1].y(), 0);
Vector3 vecC(theTrianglePt3[2].x(), theTrianglePt3[2].y(), 0);
//判断点在哪个三角形上
//2,遍历栅格集合,如果栅格里的点在此外接矩形范围内,则判断是否在三角形里,确定是否插值
//将行缩小范围
int minRow = (maxY - _theDetail.leftTopY) / _yResolution; //这里也曾经出错了,因为数组沿着Y轴是从上往下的,实际上maxY比minY离左上角更近,因此y方向的ID要注意大小和距离
int maxRow = (minY - _theDetail.leftTopY) / _yResolution;
int minCol = (minX - _theDetail.leftTopX) / _xResolution;
int maxCol = (maxX - _theDetail.leftTopX) / _xResolution;
if (maxRow >= _ySize)
{
maxRow = _ySize - 1;
}
if (maxCol >= _xSize)
{
maxCol = _xSize - 1;
}
if (minRow >= _ySize)
{
minRow = _ySize - 1;
}
if (minCol >= _xSize)
{
minCol = _xSize - 1;
}
for (int j = minRow; j <= maxRow; j++)
{
for (int i = minCol; i <= maxCol; i++)
{
Pt3 thePt3 = _rasterVecVec[j][i];
double x = thePt3.x();
double y = thePt3.y();
Pt2 thePt2 = Pt2(x, y);
//判断是否在三角形内
Vector3 vecPt(x, y, 0);
bool bTestInOrNot = this-> testPointInTriangle(vecA, vecB, vecC, vecPt);
if (bTestInOrNot)
{
//在三角形内则插值
double pointZ = -1;
bool bInterSect = getPointZfromTriangleVector(theTrianglePt3, thePt2, pointZ);
if (bInterSect)
{
//printf("插值后坐标为(%0.6f,%0.6f,%0.6f)\n", thePoint.x(), thePoint.y(), pointZ);
thePt3 = Pt3(x, y, pointZ);
}
}
_rasterVecVec[j][i] = thePt3;
}
}
}