1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
| #include <ccHObjectCaster.h> #include <ccPointCloud.h> #include <DgmOctree.h> #include <mainwindow.h>
struct ControlPoint : public CCVector3d { std::string gcp_name; int id; inline friend std::ostream& operator<<(std::ostream &os, const ControlPoint &pt) { os << std::setprecision(10) << "gcp_name: " << pt.gcp_name << ", x = " << pt.x << " , y = " << pt.y << " , z = " << pt.z; return os; } }; typedef std::vector<ControlPoint> ControlPointVec;
struct HomonymPoint : public CCVector3d { double gps_time; HomonymPoint() :CCVector3d(0.0, 0.0, 0.0), gps_time(0.0) {} std::vector<P2M::BaseType::Point3D> nearest_pts; HomonymPoint(const double x_, const double y_, const double z_) :CCVector3d(x_, y_, z_), gps_time(0.0) {} inline friend std::ostream& operator<<(std::ostream &os, const HomonymPoint &pt) { os << std::setprecision(10) << "Correspondence point gps time stamp: " << pt.gps_time << ", x = " << pt.x << " , y = " << pt.y << " , z = " << pt.z; return os; } }; typedef std::vector<HomonymPoint> HomonymPointVec;
struct checkCorrespondence { int id; ControlPoint ctrl_pt; HomonymPoint corr_pt; bool isChecked; std::vector<mba::point<2>> coo; std::vector<double> val; float dist; float dist_x; float dist_y; float dist_z; }; typedef std::vector<checkCorrespondence> checkCorrespondences;
bool getCorrespondPoints(checkCorrespondences &checkcorrs, CCVector3d &global_offset) { const ccHObject::Container &selectedEntities = MainWindow::TheInstance()->getSelectedEntities(); if (selectedEntities.empty()) return false; const ccShiftedObject* shifted = ccHObjectCaster::ToShifted(selectedEntities[0]); if (shifted) { global_offset = shifted->getGlobalShift(); } for (ccHObject* ent : selectedEntities) { ccPointCloud* pc = ccHObjectCaster::ToPointCloud(ent); if (!pc) { ccLog::LogMessage(QString::fromLocal8Bit("未选中有效点云,") + ent->getName(), ccLog::LOG_ERROR); continue; } ccOctree::Shared octree = pc->getOctree(); if (!octree) { octree = pc->computeOctree(); if (!octree) { ccLog::LogMessage(QString::fromLocal8Bit("索引构建失败,") + ent->getName(), ccLog::LOG_ERROR); continue; } } Q_ASSERT(octree != nullptr); PointCoordinateType search_radius = 1.0; unsigned char level = octree->findBestLevelForAGivenNeighbourhoodSizeExtraction(search_radius); for (int i = 0; i < checkcorrs.size(); ++i) { CCVector3 search_pt = CCVector3(checkcorrs[i].ctrl_pt.x + global_offset.x, checkcorrs[i].ctrl_pt.y + global_offset.y, checkcorrs[i].ctrl_pt.z + global_offset.z); CCLib::DgmOctree::NeighboursSet neighbour_pts; int ret_pt_num = octree->getPointsInSphericalNeighbourhood(search_pt, search_radius, neighbour_pts, level); if (ret_pt_num < 1) continue; if (neighbour_pts[0].squareDistd < checkcorrs[i].dist) { const CCVector3 *ret_pt0 = neighbour_pts[0].point; checkcorrs[i].corr_pt = HomonymPoint(ret_pt0->x - global_offset.x, ret_pt0->y - global_offset.y, ret_pt0->z - global_offset.z); } for (auto pt: neighbour_pts) { checkcorrs[i].isChecked = true; const CCVector3 *ret_pt = pt.point; checkcorrs[i].coo.push_back(mba::point<2>{ret_pt->x, ret_pt->y}); checkcorrs[i].val.emplace_back(ret_pt->z); } } } return true; }
void interpolateCoordinate(checkCorrespondence &corr, const CCVector3d &global_offset) { double minx = 0.0, maxx = 0.0, miny = 0.0, maxy = 0.0; for (auto pt : corr.coo) { minx = (std::min)(minx, pt[0]); maxx = (std::max)(maxx, pt[0]); miny = (std::min)(miny, pt[1]); maxy = (std::max)(maxy, pt[1]); } mba::point<2> lo = { minx - 3.0, miny - 3.0 }; mba::point<2> hi = { maxx + 3.0, maxy + 3.0 }; mba::index<2> grid = { 5, 5 }; mba::MBA<2> interp(lo, hi, grid, corr.coo, corr.val); corr.corr_pt.z = interp(mba::point<2>{corr.ctrl_pt.x + global_offset.x, corr.ctrl_pt.y + global_offset.y}); corr.dist_z = corr.ctrl_pt.z - corr.corr_pt.z; }
bool qualityCheck(const std::string &gcp_path, const std::string &output_path) { namespace PB = P2M::BaseType; if (!P2M::Util::FileUtility::FileExist(output_path)) { std::cerr << "Output Path: " << output_path << " doesn't exist!" << std::endl; return false; } checkCorrespondences checkcorrs; CCVector3d global_offset(0.0,0.0,0.0); loadGcpFile(gcp_path, checkcorrs, global_offset); getCorrespondPoints(checkcorrs, global_offset); for (auto &checkcorr : checkcorrs) { if (checkcorr.isChecked) { interpolateCoordinate(checkcorr, global_offset); } } return true; }
|