关于tif和笛卡儿的坐标互换

今天出了一个问题,隐藏了好几天,那就是在点云和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;

  }
 }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值