Skip to content

Commit 320e653

Browse files
authored
(VC) Fix crashes when running segmentation tool (#8)
* (Volume) Allow out of bounds reslices, (VC) Remove duplicate points on seg creation * Replace cerr with logger * Better handling of segmentation exceptions
1 parent 8f00d1c commit 320e653

File tree

4 files changed

+66
-50
lines changed

4 files changed

+66
-50
lines changed

apps/VC/CVolumeViewerWithCurve.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,9 @@ void CVolumeViewerWithCurve::DrawIntersectionCurve(void)
322322
int b{0};
323323
colorSelector->color().getRgb(&r, &g, &b);
324324
for (size_t i = 0; i < fIntersectionCurveRef->GetPointsNum(); ++i) {
325-
cv::circle(
326-
fImgMat,
327-
cv::Point2d(
328-
fIntersectionCurveRef->GetPoint(i)[0],
329-
fIntersectionCurveRef->GetPoint(i)[1]),
330-
1, cv::Scalar(b, g, r));
325+
auto p0 = fIntersectionCurveRef->GetPoint(i)[0] - 0.5;
326+
auto p1 = fIntersectionCurveRef->GetPoint(i)[1] - 0.5;
327+
cv::circle(fImgMat, cv::Point2d(p0, p1), 1, cv::Scalar(b, g, r));
331328
}
332329
}
333330
}

apps/VC/CWindow.cpp

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "CVolumeViewerWithCurve.hpp"
1010
#include "UDataManipulateUtils.hpp"
1111
#include "vc/core/types/Exceptions.hpp"
12+
#include "vc/core/util/Logging.hpp"
1213
#include "vc/meshing/OrderedPointSetMesher.hpp"
1314

1415
namespace vc = volcart;
@@ -251,7 +252,7 @@ void CWindow::CreateActions(void)
251252
void CWindow::CreateBackend()
252253
{
253254
// Setup backend runner
254-
auto worker = new VolPkgBackend();
255+
auto* worker = new VolPkgBackend();
255256
worker->moveToThread(&worker_thread_);
256257
connect(&worker_thread_, &QThread::finished, worker, &QObject::deleteLater);
257258
connect(
@@ -260,6 +261,9 @@ void CWindow::CreateBackend()
260261
connect(
261262
worker, &VolPkgBackend::segmentationFinished, this,
262263
&CWindow::onSegmentationFinished);
264+
connect(
265+
worker, &VolPkgBackend::segmentationFailed, this,
266+
&CWindow::onSegmentationFailed);
263267
connect(worker, &VolPkgBackend::progressUpdated, [=](size_t p) {
264268
progress_ = p;
265269
});
@@ -319,17 +323,14 @@ bool CWindow::InitializeVolumePkg(const std::string& nVpkgPath)
319323

320324
try {
321325
fVpkg = vc::VolumePkg::New(nVpkgPath);
322-
} catch (...) {
323-
std::cerr << "VC::Error: Volume package failed to initialize."
324-
<< std::endl;
326+
} catch (const std::exception& e) {
327+
vc::Logger()->error("Failed to initialize volpkg: {}", e.what());
325328
}
326329

327330
fVpkgChanged = false;
328331

329332
if (fVpkg == nullptr) {
330-
std::cerr
331-
<< "VC::Error: Cannot open volume package at specified location: "
332-
<< nVpkgPath << std::endl;
333+
vc::Logger()->error("Cannot open .volpkg: {}", nVpkgPath);
333334
QMessageBox::warning(
334335
this, "Error",
335336
"Volume package failed to load. Package might be corrupt.");
@@ -557,6 +558,20 @@ void CWindow::onSegmentationFinished(Segmenter::PointSet ps)
557558
UpdateView();
558559
}
559560

561+
void CWindow::onSegmentationFailed(std::string s)
562+
{
563+
vc::Logger()->error("Segmentation failed: {}", s);
564+
statusBar->showMessage(tr("Segmentation failed"));
565+
QMessageBox::critical(
566+
this, tr("VC"), QString::fromStdString("Segmentation failed:\n\n" + s));
567+
568+
setWidgetsEnabled(true);
569+
worker_progress_updater_.stop();
570+
worker_progress_.close();
571+
CleanupSegmentation();
572+
UpdateView();
573+
}
574+
560575
void CWindow::CleanupSegmentation(void)
561576
{
562577
fSegTool->setChecked(false);
@@ -634,8 +649,7 @@ void CWindow::SetUpCurves(void)
634649
{
635650
if (fVpkg == nullptr || fMasterCloud.empty()) {
636651
statusBar->showMessage(tr("Selected point cloud is empty"));
637-
std::cerr << "VC::Warning: Point cloud for this segmentation is empty."
638-
<< std::endl;
652+
vc::Logger()->warn("Segmentation point cloud is empty");
639653
return;
640654
}
641655
fIntersections.clear();
@@ -715,14 +729,18 @@ void CWindow::SetPathPointCloud(void)
715729
std::vector<cv::Vec2f> aSamplePts;
716730
fSplineCurve.GetSamplePoints(aSamplePts);
717731

718-
cv::Vec3d point;
732+
// remove duplicates
733+
auto numPts = aSamplePts.size();
734+
auto unique = std::unique(aSamplePts.begin(), aSamplePts.end());
735+
aSamplePts.erase(unique, aSamplePts.end());
736+
auto uniquePts = aSamplePts.size();
737+
vc::Logger()->warn("Removed {} duplicate points", numPts - uniquePts);
738+
739+
// setup a new master cloud
719740
fMasterCloud.setWidth(aSamplePts.size());
720741
std::vector<cv::Vec3d> points;
721-
for (size_t i = 0; i < aSamplePts.size(); ++i) {
722-
point[0] = aSamplePts[i][0];
723-
point[1] = aSamplePts[i][1];
724-
point[2] = fPathOnSliceIndex;
725-
points.push_back(point);
742+
for (const auto& pt : aSamplePts) {
743+
points.emplace_back(pt[0], pt[1], fPathOnSliceIndex);
726744
}
727745
fMasterCloud.pushRow(points);
728746

@@ -735,33 +753,33 @@ void CWindow::OpenVolume()
735753
{
736754
const QString defaultPathKey("default_path");
737755

738-
QSettings vcSettings;
756+
QSettings settings;
739757

740758
QString aVpkgPath = QString("");
741759
aVpkgPath = QFileDialog::getExistingDirectory(
742-
this, tr("Open Directory"), vcSettings.value(defaultPathKey).toString(),
760+
this, tr("Open Directory"), settings.value(defaultPathKey).toString(),
743761
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
744762
// Dialog box cancelled
745763
if (aVpkgPath.length() == 0) {
746-
std::cerr << "VC::Message: Open volume package cancelled." << std::endl;
764+
vc::Logger()->info("Open .volpkg canceled");
747765
return;
748766
}
749767

750768
// Checks the Folder Path for .volpkg extension
751-
std::string extension = aVpkgPath.toStdString().substr(
769+
auto const extension = aVpkgPath.toStdString().substr(
752770
aVpkgPath.toStdString().length() - 7, aVpkgPath.toStdString().length());
753-
if (extension.compare(".volpkg") != 0) {
771+
if (extension != ".volpkg") {
754772
QMessageBox::warning(
755773
this, tr("ERROR"),
756774
"The selected file is not of the correct type: \".volpkg\"");
757-
std::cerr << "VC::Error: Selected file: " << aVpkgPath.toStdString()
758-
<< " is of the wrong type." << std::endl;
775+
vc::Logger()->error(
776+
"Selected file is not .volpkg: {}", aVpkgPath.toStdString());
759777
fVpkg = nullptr; // Is need for User Experience, clears screen.
760778
return;
761779
}
762780

763781
QDir currentDir;
764-
vcSettings.setValue(defaultPathKey, currentDir.absoluteFilePath(aVpkgPath));
782+
settings.setValue(defaultPathKey, currentDir.absoluteFilePath(aVpkgPath));
765783

766784
// Open volume package
767785
if (!InitializeVolumePkg(aVpkgPath.toStdString() + "/")) {
@@ -770,11 +788,11 @@ void CWindow::OpenVolume()
770788

771789
// Check version number
772790
if (fVpkg->version() != VOLPKG_SUPPORTED_VERSION) {
773-
std::string msg = "VC::Error: Volume package is version " +
774-
std::to_string(fVpkg->version()) +
775-
" but this program requires a version " +
776-
std::to_string(VOLPKG_SUPPORTED_VERSION) + ".";
777-
std::cerr << msg << std::endl;
791+
const auto msg = "Volume package is version " +
792+
std::to_string(fVpkg->version()) +
793+
" but this program requires version " +
794+
std::to_string(VOLPKG_SUPPORTED_VERSION) + ".";
795+
vc::Logger()->error(msg);
778796
QMessageBox::warning(this, tr("ERROR"), QString(msg.c_str()));
779797
fVpkg = nullptr;
780798
return;
@@ -841,11 +859,10 @@ void CWindow::About(void)
841859
}
842860

843861
// Save point cloud to path directory
844-
void CWindow::SavePointCloud(void)
862+
void CWindow::SavePointCloud()
845863
{
846864
if (fMasterCloud.empty()) {
847-
std::cerr << "VC::message: Empty point cloud. Nothing to save."
848-
<< std::endl;
865+
vc::Logger()->debug("Empty point cloud. Nothing to save.");
849866
return;
850867
}
851868

@@ -859,25 +876,25 @@ void CWindow::SavePointCloud(void)
859876
return;
860877
}
861878

862-
statusBar->showMessage(tr("Volume saved."), 5000);
863-
std::cerr << "VC::message: Volume saved." << std::endl;
879+
statusBar->showMessage(tr("Volume Package saved."), 5000);
880+
vc::Logger()->info("Volume Package saved");
864881
fVpkgChanged = false;
865882
}
866883

867884
// Create new path
868885
void CWindow::OnNewPathClicked(void)
869886
{
870887
// Save if we need to
871-
if (SaveDialog() == SaveResponse::Cancelled)
888+
if (SaveDialog() == SaveResponse::Cancelled) {
872889
return;
890+
}
873891

874892
// Make a new segmentation in the volpkg
875893
auto seg = fVpkg->newSegmentation();
876-
std::string newSegmentationId = seg->id();
894+
const auto newSegmentationId = seg->id();
877895

878896
// add new path to path list
879-
QListWidgetItem* aNewPath =
880-
new QListWidgetItem(QString(newSegmentationId.c_str()));
897+
auto* aNewPath = new QListWidgetItem(QString(newSegmentationId.c_str()));
881898
fPathListWidget->addItem(aNewPath);
882899

883900
// Make sure we stay on the current slice

apps/VC/CWindow.hpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class CWindow : public QMainWindow
6363

6464
public slots:
6565
void onSegmentationFinished(Segmenter::PointSet ps);
66+
void onSegmentationFailed(std::string s);
6667

6768
public:
6869
CWindow();
@@ -112,7 +113,7 @@ private slots:
112113
void Open(void);
113114
void Close(void);
114115
void About(void);
115-
void SavePointCloud(void);
116+
void SavePointCloud();
116117

117118
void OnNewPathClicked(void);
118119
void OnPathItemClicked(QListWidgetItem* nItem);
@@ -231,6 +232,7 @@ class VolPkgBackend : public QObject
231232
signals:
232233
void segmentationStarted(size_t);
233234
void segmentationFinished(CWindow::Segmenter::PointSet ps);
235+
void segmentationFailed(std::string);
234236
void progressUpdated(size_t);
235237

236238
public slots:
@@ -240,8 +242,12 @@ public slots:
240242
segmenter.progressUpdated.connect(
241243
[=](size_t p) { progressUpdated(p); });
242244
segmentationStarted(segmenter.progressIterations());
243-
auto result = segmenter.compute();
244-
segmentationFinished(result);
245+
try {
246+
auto result = segmenter.compute();
247+
segmentationFinished(result);
248+
} catch (const std::exception& e) {
249+
segmentationFailed(e.what());
250+
}
245251
}
246252

247253
public:

core/src/Volume.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,6 @@ Reslice Volume::reslice(
185185
int width,
186186
int height) const
187187
{
188-
if (!isInBounds(center)) {
189-
throw std::range_error("center not in bounds");
190-
}
191-
192188
auto xnorm = cv::normalize(xvec);
193189
auto ynorm = cv::normalize(yvec);
194190
auto origin = center - ((width / 2) * xnorm + (height / 2) * ynorm);

0 commit comments

Comments
 (0)