10 #include <pcl/kdtree/kdtree_flann.h>
11 #include <pcl/point_cloud.h>
19 #include <QMainWindow>
20 #include <QMessageBox>
48 #include <opencv2/highgui/highgui.hpp>
49 #include <opencv2/imgproc/imgproc.hpp>
50 #include <opencv2/opencv.hpp>
55 ccManualSeg::ccManualSeg(QObject* parent)
59 m_segmentationPoly(0),
62 m_segmentationPoly =
new ccPolyline(m_polyVertices);
63 m_segmentationPoly->setForeground(
true);
65 m_segmentationPoly->showColors(
true);
66 m_segmentationPoly->set2DMode(
true);
74 QList<QAction*> ccManualSeg::getActions() {
76 m_action =
new QAction(
getName(),
this);
78 m_action->setIcon(QIcon(QString::fromUtf8(
79 ":/CC/plugin/qManualSeg/cyberbuildIcon.png")));
82 connect(m_action, &QAction::triggered,
this, &ccManualSeg::doAction);
85 return QList<QAction*>{
107 "Define and/or close the segmentation polygon first! (right "
126 for (
unsigned i = 0; i < vertices->
size(); ++i) {
139 for (
unsigned j = 0; j < poly->
size(); ++j) {
149 for (
int j = 0; j < static_cast<int>(gCloud->
size()); ++j) {
164 visibilityArrayBase2[j] =
166 cnt = cnt + visibilityArrayBase2[j];
167 if (visibilityArrayBase2[j] == 1) ptsIdx.push_back(j);
176 std::vector<cloudViewer::PointProjectionTools::IndexedCCVector2>
point;
177 std::list<cloudViewer::PointProjectionTools::IndexedCCVector2*> hullPoint2;
179 for (
unsigned i = 0; i < stone->
size(); ++i)
192 vector<unsigned> Vec;
193 for (
int i = 0; i < (hullPoint2.size()); ++i) {
194 list<cloudViewer::PointProjectionTools::IndexedCCVector2*>::iterator
195 it = hullPoint2.begin();
215 int cnt = Vec.size();
232 vector<int> ccManualSeg::stIdFromPtId(std::vector<int> pts,
233 std::vector<pair<int, int>> pairs) {
237 if (!(find(v.begin(), v.end(), e) != v.end()))
238 v.push_back(pairs[e].second);
240 sort(v.begin(), v.end());
242 v.erase(unique(v.begin(), v.end()), v.end());
248 vector<int> ccManualSeg::ptIdFromStId(std::vector<int> stIdx,
249 std::vector<pair<int, int>> pairs) {
253 for (
unsigned int i = 0; i < pairs.size(); i++)
254 if (pairs[i].second == e) v.push_back(pairs[i].first);
260 pair<double, double>
getCentroid(vector<pair<double, double>> V) {
274 vector<int>
getKNN(pair<double, double> P,
275 vector<pair<double, double>> V,
277 if (k > V.size()) k = V.size();
279 vector<pair<int, double>> distances;
283 for (
unsigned i = 0; i < V.size(); ++i) {
284 d = sqrt(pow((P.first - V[i].first), 2) +
285 pow((P.second - V[i].second), 2));
289 sort(distances.begin(), distances.end(),
290 [](
auto& left,
auto& right) { return left.second < right.second; });
292 for (
unsigned i = 0; i < k; ++i) {
293 t[i] = distances[i].first;
301 vector<pair<double, double>> ref) {
305 vector<pair<double, double>> allpts = tar;
307 sort(allpts.begin(), allpts.end());
308 allpts.erase(unique(allpts.begin(), allpts.end()), allpts.end());
310 allpts.insert(allpts.end(), ref.begin(), ref.end());
311 sort(allpts.begin(), allpts.end());
315 allpts.erase(unique(allpts.begin(), allpts.end()), allpts.end());
317 n = n0 - allpts.size();
324 vector<vector<int>> CommonPtsIdx(2);
325 vector<pair<float, float>> Pts1(Cl1->
size());
326 vector<pair<float, float>> Pts2(Cl2->
size());
327 vector<pair<float, float>> Pts1C;
328 vector<pair<float, float>> Pts2C;
329 vector<pair<float, float>> allPts;
330 vector<pair<float, float>> uniquePts;
331 vector<pair<float, float>> commonPts;
333 for (
unsigned i = 0; i < Cl1->
size(); i++) {
336 for (
unsigned i = 0; i < Cl2->
size(); i++) {
343 sort(Pts1C.begin(), Pts1C.end());
344 sort(Pts2C.begin(), Pts2C.end());
346 Pts1C.erase(unique(Pts1C.begin(), Pts1C.end()), Pts1C.end());
347 Pts2C.erase(unique(Pts2C.begin(), Pts2C.end()), Pts2C.end());
350 allPts.insert(allPts.end(), Pts2C.begin(), Pts2C.end());
351 sort(allPts.begin(), allPts.end());
354 uniquePts.erase(unique(uniquePts.begin(), uniquePts.end()),
356 std::set_difference(allPts.begin(), allPts.end(), uniquePts.begin(),
358 std::inserter(commonPts, commonPts.end()));
359 sort(commonPts.begin(), commonPts.end());
361 for (
unsigned i = 0; i < Cl1->
size(); i++) {
362 if (std::binary_search(commonPts.begin(), commonPts.end(), Pts1[i]))
363 CommonPtsIdx[0].push_back(i);
366 for (
unsigned i = 0; i < Cl2->
size(); i++) {
367 if (std::binary_search(commonPts.begin(), commonPts.end(), Pts2[i]))
368 CommonPtsIdx[1].push_back(i);
376 vector<Point>& idxPxS,
377 vector<int>& idxPx1DS,
381 for (
int y = 0; y < corrMatS.rows; y++) {
382 for (
int x = 0; x < corrMatS.cols; x++) {
383 corrMatS.at<
int>(y, x) = cntC;
389 int s = cloud->
size();
391 for (
int i = 0; i < s; i++) {
394 int z =
floor(pointC0->
z);
395 int x =
floor(pointC0->
x);
396 imageBWS.at<
uchar>(z, x) = 255;
400 idxPxS.push_back(Point(z, x));
401 idxPx1DS.push_back(corrMatS.at<
int>(z, x));
409 toSkel = 255 * cv::Mat::ones(I.rows, I.cols, CV_8U) - I;
414 cv::Mat skel(toSkel.size(), CV_8U, cv::Scalar(0));
419 cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
424 cv::erode(toSkel, eroded, element);
425 cv::dilate(eroded, temp, element);
426 cv::subtract(toSkel, temp, temp);
427 cv::bitwise_or(skel, temp, skel);
428 eroded.copyTo(toSkel);
430 done = (cv::countNonZero(toSkel) == 0);
432 }
while (!done && (iterations < 100));
438 vector<int> commonList;
442 for (
auto& e : listNew) {
443 for (
auto& ee : listOld) {
445 commonList.push_back(cnt);
456 std::vector<cloudViewer::PointProjectionTools::IndexedCCVector2>
point;
457 std::list<cloudViewer::PointProjectionTools::IndexedCCVector2*> hullPoint2;
459 for (
unsigned i = 0; i < V.size(); ++i)
472 vector<unsigned> Vec;
473 for (
int i = 0; i < (hullPoint2.size()); ++i) {
474 list<cloudViewer::PointProjectionTools::IndexedCCVector2*>::iterator
475 it = hullPoint2.begin();
496 int cnt = Vec.size();
520 timeinfo = localtime(&rawtime);
522 strftime(buffer,
sizeof(buffer),
"%H:%M:%S", timeinfo);
523 std::string str(buffer);
550 f_cloudMortar->
scale(100, 1000, 100);
553 int rowsM =
ceil(maxBox.
z);
554 int colsM =
ceil(maxBox.
x);
556 cv::Mat corrMatM = Mat::zeros(rowsM, colsM, CV_32F);
557 vector<Point> idxPxM;
558 vector<int> idxPxM1D;
559 cv::Mat imageBWS = Mat::zeros(rowsM, colsM, CV_8U);
561 cloud2binary(f_cloudMortar, corrMatM, idxPxM, idxPxM1D, imageBWS);
564 Mat skel =
skeleton(imageBWS,
false);
566 f_cloudMortar->
scale(0.01, 0.001, 0.01);
569 vector<int> pixelsSkel;
570 for (
int i = 0; i < skel.rows; i++) {
571 for (
int j = 0; j < skel.cols; j++) {
572 unsigned char a = skel.at<
char>(i, j);
574 int idx = corrMatM.at<
int>(i, j);
575 pixelsSkel.push_back(idx);
580 vector<int> idxCloudMortarSkel =
583 for (
auto e : idxCloudMortarSkel) {
598 skelM, 0.01, modParams, 0, 0);
608 pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloudStones(
609 new pcl::PointCloud<pcl::PointXYZ>);
610 pcl_cloudStones->width = f_cloudStones->
size();
611 pcl_cloudStones->height = 1;
612 pcl_cloudStones->points.resize(pcl_cloudStones->width *
613 pcl_cloudStones->height);
615 for (
size_t i = 0; i < f_cloudStones->
size(); ++i) {
616 pcl_cloudStones->points[i].x = f_cloudStones->
getPoint(i)->
x;
617 pcl_cloudStones->points[i].y = f_cloudStones->
getPoint(i)->
y;
618 pcl_cloudStones->points[i].z = f_cloudStones->
getPoint(i)->
z;
621 pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;
623 kdtree.setInputCloud(pcl_cloudStones);
626 vector<double> distStD, dist3St, distStD2;
627 vector<double> distStWidth;
628 vector<double> distStW;
629 for (
int i = 0; i < f_skelMortar->
size(); i++) {
630 pcl::PointXYZ searchPoint;
632 searchPoint.x = f_skelMortar->
getPoint(i)->
x;
633 searchPoint.y = f_skelMortar->
getPoint(i)->
y;
634 searchPoint.z = f_skelMortar->
getPoint(i)->
z;
636 std::vector<int> pointIdxRadiusSearch;
637 std::vector<float> pointRadiusSquaredDistance;
640 pcl::PointXYZ nnPoint;
642 if (kdtree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch,
643 pointRadiusSquaredDistance) > 0) {
644 nnPoint.x = pcl_cloudStones->points[pointIdxRadiusSearch[0]].x;
645 nnPoint.y = pcl_cloudStones->points[pointIdxRadiusSearch[0]].y;
646 nnPoint.z = pcl_cloudStones->points[pointIdxRadiusSearch[0]].z;
648 double disty =
abs(searchPoint.y - nnPoint.y);
649 double distx =
abs(searchPoint.x - nnPoint.x);
650 double distz =
abs(searchPoint.z - nnPoint.z);
651 double dist3 = sqrt(distx * distx +
656 distStD.push_back(disty * 1000);
657 dist3St.push_back(dist3);
661 double dist1y = 1000;
662 double dist2y = 1000;
665 for (
size_t j = 0; j < pointIdxRadiusSearch.size(); ++j) {
668 pcl_cloudStones->points[pointIdxRadiusSearch[j]]
672 pcl_cloudStones->points[pointIdxRadiusSearch[j]].z);
675 pcl_cloudStones->points[pointIdxRadiusSearch[j]].y);
677 sqrt(
abs(distx) *
abs(distx) +
abs(distz) *
abs(distz));
680 pointIdxRadiusSearch[j]);
688 if (dist3 < dist1) dist1 = dist3;
691 if (idxSt != idx1 & idx2 == -1) {
697 if (dist3 < dist2) dist2 = dist3;
705 if (idx1 > -1 & idx2 == -1 &
707 distStW.push_back(dist1 * 1000);
708 distStD2.push_back(dist1y * 1000);
709 }
else if (idx1 > -1 & idx2 > -1) {
710 distStW.push_back((dist1 + dist2) * 1000);
711 distStD2.push_back((dist1y + dist2y) / 2 * 1000);
719 distStD2.push_back(100);
720 dist3St.push_back(200);
722 distStW.push_back(200);
730 "Mortar relative depth (mm)");
732 sfIdxD = f_skelMortar->
addScalarField(
"Mortar relative depth (mm)");
740 for (
unsigned int i = 0; i < distStD2.size(); i++) {
741 double index =
static_cast<double>(distStD2.at(i));
753 "Mortar relative width (mm)");
755 sfIdxW = f_skelMortar->
addScalarField(
"Mortar relative width (mm)");
763 for (
unsigned int i = 0; i < distStW.size(); i++) {
764 double index =
static_cast<double>(distStW.at(i));
775 f_skelMortar->
showSF(
true);
776 f_skelMortar->
setName(
"Mortar Maps");
780 void ccManualSeg::doAction() {
788 timeinfo = localtime(&rawtime);
790 strftime(buffer,
sizeof(buffer),
"%Y%m%d_%H%M%S", timeinfo);
791 std::string str(buffer);
796 ofstream auto_seg_log;
800 time_t my_time = time(
NULL);
802 if (
m_app ==
nullptr) {
822 std::vector<int> idxPoly;
840 if (contourfolder.size() >= 0) {
841 for (
int i = 0; i < contourfolder.size(); ++i) {
842 ccHObject* ContoursContainer = contourfolder[i];
844 QString s = ContoursContainer->
getName();
845 string s0 = s.toStdString();
846 string s1 =
"tone contours";
848 if (s0.find(s1) != std::string::npos) {
854 if (oldMortarMaps.size() >= 0) {
855 for (
int i = 0; i < contourfolder.size(); ++i) {
859 string s0 = s.toStdString();
860 string s1 =
"Mortar Maps";
862 if (s0.find(s1) != std::string::npos) {
880 int sizeClouds = 1000000000;
885 int n = polys.size();
888 QFileInfo fileInfo(pcs.front()->getFullPath());
889 QDir dir(fileInfo.absolutePath());
890 QString autoSegLogFile = dir.absoluteFilePath(
filename.c_str());
893 for (
int i = 0; i < pcs.size(); ++i) {
896 string s0 = s.toStdString();
901 if ((s0.find(s3) != std::string::npos) &&
902 (s0.find(s1) != std::string::npos)) {
904 string cComment =
"reference stone cloud found!";
905 QString qComment = QString::fromUtf8(cComment.c_str());
910 auto_seg_log << stamp <<
" Reference stone cloud found"
914 if ((s0.find(s3) != std::string::npos) &&
915 (s0.find(s2) != std::string::npos)) {
917 string cComment =
"reference mortar cloud found!";
918 QString qComment = QString::fromUtf8(cComment.c_str());
923 auto_seg_log << stamp <<
" Reference mortar cloud found"
927 if (!(s0.find(s3) != std::string::npos) &&
928 (s0.find(s1) != std::string::npos)) {
930 string cComment =
"Stone cloud found!";
931 QString qComment = QString::fromUtf8(cComment.c_str());
936 auto_seg_log << stamp <<
" Stone cloud found" <<
endl;
939 if (!(s0.find(s3) != std::string::npos) &&
940 (s0.find(s2) != std::string::npos)) {
942 string cComment =
"Mortar cloud found!";
943 QString qComment = QString::fromUtf8(cComment.c_str());
948 auto_seg_log << stamp <<
" Mortar cloud found" <<
endl;
953 if (n == 0 && refStone != -1 && idxStone != -1 &&
954 refMortar != -1 && idxMortar != -1) {
961 cloudStone =
static_cast<ccPointCloud*
>(pcs.at(idxStone));
962 cloudMortar =
static_cast<ccPointCloud*
>(pcs.at(idxMortar));
968 "At least one cloud and a polyline are required",
974 if (idxMortar != -1 && idxStone != -1) {
975 cloudStone =
static_cast<ccPointCloud*
>(pcs.at(idxStone));
976 cloudMortar =
static_cast<ccPointCloud*
>(pcs.at(idxMortar));
978 if (idxMortar == -1 && idxStone == -1) {
981 for (
int i = 0; i < pcs.size(); ++i) {
985 if (cl->
size() > 100) {
993 "For manual segmentation leave only one cloud "
999 cloudMortar =
static_cast<ccPointCloud*
>(pcs.at(idxMortar));
1007 "Only one cloud has been foud",
1011 "for manual segmentation please change it's name "
1012 "so that it doesn't contain the sequence 'stone' "
1026 unsigned pointSizeMortar = cloudMortar->
getPointSize();
1028 std::vector<int> recIdx;
1029 std::vector<int> polyIdx;
1032 for (
unsigned int i = 0; i < polys.size(); i++) {
1035 int j = poly->
size();
1042 float dx1 = x1 - x0;
1043 float dx2 = x3 - x2;
1046 if (poly->
size() == 4 && dx1 == dx2) {
1047 recIdx.push_back(i);
1049 polyIdx.push_back(i);
1055 vector<vector<pair<int, int>>> stonePairs(2);
1056 vector<vector<int>> mortarPoints(2);
1057 vector<int> allStIdx;
1062 for (
unsigned int i = 0; i < cloudMortar->
size(); i++)
1063 mortarPoints[0].push_back(i);
1067 if (cloudStone->
size() > 0) {
1068 for (
unsigned int i = 0; i < cloudStone->
size(); i++) {
1070 allStIdx.push_back(stIdSF->
getValue(i));
1073 sort(allStIdx.begin(), allStIdx.end());
1075 int n = allStIdx.size();
1076 maxId = allStIdx[n - 1];
1080 auto_seg_log <<
" Evaluating polylines ("
1081 << polyIdx.size() + recIdx.size() <<
")..." <<
endl;
1084 if (recIdx.size() != 0) {
1086 auto_seg_log <<
" Deleting incorrectly identified stones ("
1087 << recIdx.size() <<
")..." <<
endl;
1089 for (
auto i : recIdx) {
1092 auto_seg_log << stamp <<
" Polyline " << cntRect <<
"/"
1093 << recIdx.size() <<
endl;
1100 v = pointIdx(cloudStone, poly);
1101 stId = stIdFromPtId(v, stonePairs[0]);
1104 for (
unsigned int i = 0; i < stonePairs[0].size(); ++i) {
1105 if (stonePairs[0][i].second == e) {
1106 stonePairs[0][i].second = -1;
1107 mortarPoints[1].push_back(stonePairs[0][i].first);
1115 if (polyIdx.size() != 0) {
1117 auto_seg_log <<
" Correcting boundaries of stones ("
1118 << polyIdx.size() <<
")..." <<
endl;
1120 for (
auto i : polyIdx) {
1123 auto_seg_log << stamp <<
" Polyline " << cntPoly <<
"/"
1124 << polyIdx.size() <<
endl;
1131 vs = pointIdx(cloudStone, poly);
1132 vm = pointIdx(cloudMortar, poly);
1137 if (vm.size() == 0 &&
1141 kLabel =
" (Removing stone)";
1143 if (vs.size() == 0 && vm.size() != 0) {
1145 kLabel =
" (Adding new stone)";
1147 if (vs.size() != 0 && vm.size() != 0) {
1149 kLabel =
" (Correcting previously segmented stone)";
1153 auto_seg_log << stamp <<
" Case " << k << kLabel <<
endl;
1160 stId = stIdFromPtId(vs, stonePairs[0]);
1162 if (stId.size() == 1 && stId[0] == -1) {
1165 stonePairs[0][e].second = maxId;
1168 vector<int> tempMortar = mortarPoints[1];
1169 vector<int> resMortar;
1170 sort(tempMortar.begin(), tempMortar.end());
1171 std::set_difference(
1172 tempMortar.begin(), tempMortar.end(),
1173 vs.begin(), vs.end(),
1174 std::inserter(resMortar, resMortar.end()));
1176 mortarPoints[1] = resMortar;
1181 vall = ptIdFromStId(stId, stonePairs[0]);
1183 std::set_difference(vall.begin(), vall.end(),
1184 vs.begin(), vs.end(),
1185 std::inserter(vr, vr.end()));
1188 mortarPoints[1].push_back(e);
1189 stonePairs[0][e].second = -1;
1198 stonePairs[1].push_back(
make_pair(e, maxId));
1199 (mortarPoints[0])[e] = -1;
1208 stId = stIdFromPtId(
1214 for (
auto e : stId) {
1215 if (e < minId) minId = e;
1235 mortarPoints[0][e] =
1239 vall = ptIdFromStId(
1240 stId, stonePairs[0]);
1244 for (
auto e : vall) {
1245 stonePairs[0][e].second =
1250 sort(vs.begin(), vs.end());
1251 sort(vall.begin(), vall.end());
1252 std::set_difference(
1253 vall.begin(), vall.end(), vs.begin(), vs.end(),
1259 if (vr.size() > 0) {
1267 mortarPoints[1].push_back(e);
1268 stonePairs[0][e].second =
1274 sort(mortarPoints[1].begin(), mortarPoints[1].end());
1275 mortarPoints[1].erase(unique(mortarPoints[1].begin(),
1276 mortarPoints[1].end()),
1277 mortarPoints[1].end());
1279 if (stId[0] == -1) {
1280 vector<int> tempMortar = mortarPoints[1];
1281 vector<int> resMortar;
1282 sort(tempMortar.begin(), tempMortar.end());
1283 std::set_difference(
1284 tempMortar.begin(), tempMortar.end(),
1285 vs.begin(), vs.end(),
1286 std::inserter(resMortar, resMortar.end()));
1288 mortarPoints[1] = resMortar;
1308 for (
unsigned int i = 0; i < cloudStone->
size(); ++i) {
1319 for (
unsigned int i = 0; i < cloudMortar->
size(); ++i) {
1335 vector<pair<int, int>> rStPairs;
1338 for (
auto e : stonePairs[0]) {
1339 if (e.second != -1) rStPairs.push_back(e);
1342 for (
unsigned int i = 0; i < rStPairs.size(); ++i) {
1347 pt = cloudStone->
getPoint(rStPairs[i].first);
1354 if (stonePairs[1].
size() != 0) {
1355 for (
auto i = 0; i < stonePairs[1].size(); ++i) {
1360 pt = cloudMortar->
getPoint(stonePairs[1][i].first);
1380 for (
unsigned int i = 0; i < rStPairs.size(); ++i) {
1381 int index =
static_cast<int>(rStPairs[i].second);
1386 if (stonePairs[1].
size() != 0) {
1387 for (
auto i = 0; i < stonePairs[1].size(); ++i) {
1388 int index =
static_cast<int>(stonePairs[1][i].second);
1389 new_stIdSF->
setValue(rStPairs.size() + i, index);
1399 for (
auto e : mortarPoints[0]) {
1413 if (mortarPoints[1].
size() != 0) {
1414 for (
auto e : mortarPoints[1]) {
1429 if (idxStone == -1) {
1435 int nbpts = new_CloudStone->
size();
1436 vector<pair<int, int>> nstonePairs;
1437 vector<int> nallStIdx;
1444 for (
unsigned int i = 0; i < nbpts; i++) {
1446 nallStIdx.push_back(nstIdSF->
getValue(i));
1450 sort(nallStIdx.begin(), nallStIdx.end());
1451 nallStIdx.erase(unique(nallStIdx.begin(), nallStIdx.end()),
1455 vector<vector<int>> vecStones(nallStIdx.size());
1457 sort(nstonePairs.begin(), nstonePairs.end(),
1458 [](
auto& left,
auto& right) {
1459 return left.second < right.second;
1462 int old_idx = nstonePairs[0].second;
1465 for (
unsigned i = 0; i < nstonePairs.size(); i++) {
1466 if (nstonePairs[i].second == old_idx) {
1467 nstonePairs[i].second = new_idx;
1468 vecStones[new_idx].push_back(nstonePairs[i].first);
1472 old_idx = nstonePairs[i].second;
1473 nstonePairs[i].second = new_idx;
1474 vecStones[new_idx].push_back(nstonePairs[i].first);
1478 sort(nstonePairs.begin(), nstonePairs.end(),
1479 [](
auto& left,
auto& right) { return left.first < right.first; });
1482 vector<int> stIdShuffle;
1483 for (
auto e : nstonePairs) {
1484 stIdShuffle.push_back(e.second);
1487 sort(stIdShuffle.begin(), stIdShuffle.end());
1489 stIdShuffle.erase(unique(stIdShuffle.begin(), stIdShuffle.end()),
1492 auto rng = std::default_random_engine{};
1493 std::shuffle(stIdShuffle.begin(), stIdShuffle.end(), rng);
1496 for (
unsigned int i = 0; i < nbpts; i++) {
1498 static_cast<int>(stIdShuffle[nstonePairs[i].second]);
1504 auto_seg_log <<
" Starting mortar maps generation..." <<
endl;
1509 auto_seg_log << stamp <<
" Mortar maps OK" <<
endl;
1522 auto_seg_log <<
" Starting contours regeneration" <<
endl;
1526 if (vecStones.size() > 0) {
1527 for (
auto ve : vecStones) {
1528 string s_name =
"stone " +
to_string(cntSt);
1529 QString qs_name = QString::fromUtf8(s_name.c_str());
1533 auto_seg_log << stamp <<
" Polyline " << cntSt <<
"/"
1534 << vecStones.size() - 1 <<
endl;
1536 if (ve.size() > 0) {
1538 nContoursContainer->
addChild(contour);
1544 auto_seg_log << stamp <<
" Contours regeneration done" <<
endl;
1549 m_app->
addToDB(new_CloudStone,
true,
true,
false,
true);
1550 m_app->
addToDB(new_CloudMortar,
true,
true,
false,
true);
1551 m_app->
addToDB(nContoursContainer,
true,
true,
false,
true);
constexpr unsigned char POINT_VISIBLE
constexpr unsigned char POINT_HIDDEN
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Dialog for importing a 2D revolution profile (qSRA plugin)
virtual QString getName() const override
Returns (short) name (for menu entry, etc.)
virtual QString getDescription() const override
Returns long name/description (for tooltip, etc.)
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
A 3D cloud interface with associated features (color, normals, octree, etc.)
unsigned char getPointSize() const
Returns current point size.
void setPointSize(unsigned size=0)
Sets point size.
virtual VisibilityTableType & getTheVisibilityArray()
Returns associated visibility array.
virtual bool resetVisibilityArray()
Resets the associated visibility array.
std::vector< unsigned char > VisibilityTableType
Array of "visibility" information for each point.
static ccGenericPointCloud * ToGenericPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccGenericPointCloud.
Hierarchical CLOUDVIEWER Object.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
unsigned filterChildren(Container &filteredChildren, bool recursive=false, CV_CLASS_ENUM filter=CV_TYPES::OBJECT, bool strict=false) const
Collects the children corresponding to a certain pattern.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
ccPointCloud * m_polyVertices
Segmentation polyline vertices.
ccPolyline * m_segmentationPoly
Segmentation polyline.
virtual QString getName() const
Returns object name.
virtual void setName(const QString &name)
Sets object name.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
virtual void scale(PointCoordinateType fx, PointCoordinateType fy, PointCoordinateType fz, CCVector3 center=CCVector3(0, 0, 0)) override
Multiplies all coordinates by constant factors (one per dimension)
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
void clear() override
Clears the entity from all its points and features.
virtual ccPointCloud & Translate(const Eigen::Vector3d &translation, bool relative=true) override
Apply translation to the geometry coordinates.
const ecvColor::Rgb & getPointColor(unsigned pointIndex) const override
Returns color corresponding to a given point.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
ccPointCloud * partialClone(const cloudViewer::ReferenceCloud *selection, int *warnings=nullptr, bool withChildEntities=true) const
Creates a new point cloud object from a ReferenceCloud (selection)
bool reserveThePointsTable(unsigned _numberOfPoints)
Reserves memory to store the points coordinates.
bool is2DMode() const
Returns whether the polyline is considered as 2D or 3D.
void showVertices(bool state)
Sets whether to display or hide the polyline vertices.
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
Standard ECV plugin interface.
ecvMainAppInterface * m_app
Main application interface.
virtual unsigned size() const =0
Returns the number of points.
A generic 3D point cloud with index-based and presistent access to points.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
void getBoundingBox(CCVector3 &bbMin, CCVector3 &bbMax) override
unsigned size() const override
ScalarType getPointScalarValue(unsigned pointIndex) const override
const CCVector3 * getPoint(unsigned index) const override
void setClosed(bool state)
Sets whether the polyline is closed or not.
void clear(bool unusedParam=true) override
Clears the cloud.
bool isClosed() const
Returns whether the polyline is closed or not.
A very simple point cloud (no point duplication)
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
virtual GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
A simple scalar field (to be associated to a point cloud)
virtual void computeMinAndMax()
Determines the min and max values.
ScalarType & getValue(std::size_t index)
void setValue(std::size_t index, ScalarType value)
virtual ccHObject * dbRootObject()=0
Returns DB root (as a ccHObject)
virtual QMainWindow * getMainWindow()=0
Returns main window.
virtual void setView(CC_VIEW_ORIENTATION view)=0
virtual void refreshAll(bool only2D=false, bool forceRedraw=true)=0
Redraws all GL windows that have the 'refresh' flag on.
virtual void addToDB(ccHObject *obj, bool updateZoom=false, bool autoExpandDBTree=true, bool checkDimensions=false, bool autoRedraw=true)=0
virtual void dispToConsole(QString message, ConsoleMessageLevel level=STD_CONSOLE_MESSAGE)=0
virtual void removeFromDB(ccHObject *obj, bool autoDelete=true)=0
Removes an entity from main db tree.
__host__ __device__ int2 abs(int2 v)
QTextStream & endl(QTextStream &stream)
CLOUDVIEWER_HOST_DEVICE Pair< First, Second > make_pair(const First &_first, const Second &_second)
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
constexpr Rgb cyan(0, MAX, MAX)
constexpr Rgb green(0, MAX, 0)
std::string to_string(const T &n)
ccPolyline * contourPoly(ccPointCloud *stone)
vector< int > setIntersectIdxPixs1D(vector< int > listNew, vector< int > listOld)
ccPolyline * contourPoly2(ccPointCloud *cloud0, vector< int > V, QString name)
ccPointCloud * getMortarMaps(ccPointCloud *f_cloudStones, ccPointCloud *f_cloudMortar)
Mat skeleton(Mat I, bool flagInv)
void cloud2binary(ccPointCloud *cloud, Mat &corrMatS, vector< Point > &idxPxS, vector< int > &idxPx1DS, Mat &imageBWS)
vector< vector< int > > getCommonPtsIdx(ccPointCloud *Cl1, ccPointCloud *Cl2)
pair< double, double > getCentroid(vector< pair< double, double >> V)
int getNCommonPts(vector< pair< double, double >> tar, vector< pair< double, double >> ref)
vector< int > getKNN(pair< double, double > P, vector< pair< double, double >> V, int k=3)
OpenGL camera parameters.
bool project(const CCVector3d &input3D, CCVector3d &output2D, bool *inFrustum=nullptr) const
Projects a 3D point in 2D (+ normalized 'z' coordinate)