diff --git a/CMakeLists.txt b/CMakeLists.txt
index 91cd0d3..08b1fb7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,6 +27,8 @@ endif()
include_directories(${catkin_INCLUDE_DIRS} src/ ${QT5_INCLUDE_DIRS} ${GLEW_INCLUDE_DIRS} /usr/include/eigen3)
+add_compile_definitions(ASSETS_PATH="${CMAKE_CURRENT_SOURCE_DIR}/assets")
+
set(CMAKE_INCLUDE_CURRENT_DIR ON) # needs to be activated for qt generated files in build directory.
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_FLAGS "-std=c++11 -O3 -Wall ${CMAKE_CXX_FLAGS}")
diff --git a/README.md b/README.md
index 0ab99e6..2b10e4a 100644
--- a/README.md
+++ b/README.md
@@ -120,3 +120,7 @@ If you're using the tool in your research, it would be nice if you cite our [pap
```
We used the tool to label SemanticKITTI, which contains overall over 40.000 scans organized in 20 sequences.
+
+## Asset Attribution
+
+Camera icon made by [Ilham Fitrotul Hayat](https://www.flaticon.com/authors/ilham-fitrotul-hayat) from [www.flaticon.com](https://www.flaticon.com/). Dark/Light background toggle icon made by [Icon-Hubs](https://www.flaticon.com/authors/icon-hubs) from [www.flaticon.com](https://www.flaticon.com/). Image icon made by [feen](https://www.flaticon.com/authors/feen) from [www.flaticon.com](https://www.flaticon.com/).
\ No newline at end of file
diff --git a/assets/camera.png b/assets/camera.png
new file mode 100644
index 0000000..c21f102
Binary files /dev/null and b/assets/camera.png differ
diff --git a/assets/dark_mode.png b/assets/dark_mode.png
new file mode 100644
index 0000000..e29d8aa
Binary files /dev/null and b/assets/dark_mode.png differ
diff --git a/assets/insert_picture_icon.png b/assets/insert_picture_icon.png
new file mode 100644
index 0000000..2c742b1
Binary files /dev/null and b/assets/insert_picture_icon.png differ
diff --git a/assets/insert_picture_icon_2.png b/assets/insert_picture_icon_2.png
new file mode 100644
index 0000000..da6d0de
Binary files /dev/null and b/assets/insert_picture_icon_2.png differ
diff --git a/src/MainFrame.ui b/src/MainFrame.ui
index 6e79d27..38ac454 100644
--- a/src/MainFrame.ui
+++ b/src/MainFrame.ui
@@ -361,7 +361,7 @@
0
0
- 200
+ 253
706
@@ -1466,6 +1466,7 @@
+
@@ -1581,6 +1582,11 @@
screenshot
+
+
+ Toggle Dark Background
+
+
diff --git a/src/labeler.cpp b/src/labeler.cpp
index d7a73c3..8a2e7dc 100644
--- a/src/labeler.cpp
+++ b/src/labeler.cpp
@@ -11,7 +11,10 @@ int main(int argc, char** argv) {
frame.show();
frame.resize(1200, 900);
-// std::cout << glow::GlCapabilities::getInstance() << std::endl;
+ // QPalette pal = app.palette();
+ // pal.setColor(QPalette::Window, Qt::black);
+ // app.setPalette(pal);
+// std::cout << glow::GlCapabilities::getInstance() << std::endl;
return app.exec();
}
diff --git a/src/widget/KittiReader.cpp b/src/widget/KittiReader.cpp
index 20f3ce9..47a3936 100644
--- a/src/widget/KittiReader.cpp
+++ b/src/widget/KittiReader.cpp
@@ -9,6 +9,9 @@
#include "rv/string_utils.h"
#include
+#include
+
+namespace fs = boost::filesystem;
void KittiReader::initialize(const QString& directory) {
velodyne_filenames_.clear();
@@ -37,8 +40,13 @@ void KittiReader::initialize(const QString& directory) {
// create label dir, etc.
QDir labels_dir(base_dir_.filePath("labels"));
+
// find corresponding label files.
- if (!labels_dir.exists()) base_dir_.mkdir("labels");
+ if (!labels_dir.exists())
+ {
+ std::cout << "Found no labels. Creating labels directory\n";
+ base_dir_.mkdir("labels");
+ }
for (uint32_t i = 0; i < velodyne_filenames_.size(); ++i) {
QString filename = QFileInfo(QString::fromStdString(velodyne_filenames_[i])).baseName() + ".label";
@@ -55,18 +63,17 @@ void KittiReader::initialize(const QString& directory) {
out.close();
}
-
label_filenames_.push_back(labels_dir.filePath(filename).toStdString());
}
- std::string missing_img = QDir::currentPath().toStdString() + "/../assets/missing.png";
+ fs::path missing_img = fs::path(ASSETS_PATH) / "missing.png";
QDir image_dir(base_dir_.filePath("image_2"));
for (uint32_t i = 0; i < velodyne_filenames_.size(); ++i) {
QString filename = QFileInfo(QString::fromStdString(velodyne_filenames_[i])).baseName() + ".png";
if (image_dir.exists(filename)) {
image_filenames_.push_back(image_dir.filePath(filename).toStdString());
} else {
- image_filenames_.push_back(missing_img);
+ image_filenames_.push_back(missing_img.string());
}
}
@@ -207,9 +214,13 @@ void KittiReader::initialize(const QString& directory) {
uint32_t instanceId = (instance_label >> 16) & uint32_t(0xFFFF);
uint32_t label = instance_label & uint32_t(0xFFFF);
if (maxInstanceIds_.find(label) == maxInstanceIds_.end())
+ {
maxInstanceIds_[label] = instanceId;
+ }
else
+ {
maxInstanceIds_[label] = std::max(instanceId, maxInstanceIds_[label]);
+ }
}
}
diff --git a/src/widget/Mainframe.cpp b/src/widget/Mainframe.cpp
index eb6e02c..fed364b 100644
--- a/src/widget/Mainframe.cpp
+++ b/src/widget/Mainframe.cpp
@@ -16,8 +16,10 @@
#include
#include
+#include
using namespace glow;
+namespace fs = boost::filesystem;
// see https://stackoverflow.com/a/24349347
template
@@ -52,6 +54,9 @@ Mainframe::Mainframe() : mChangesSinceLastSave(false) {
connect(ui.actionPolygonMode, &QAction::triggered,
[this]() { changeMode(Viewport::POLYGON, ui.actionPolygonMode->isChecked()); });
+ connect(ui.actionToggleDarkBackground, &QAction::triggered,
+ [this]() { ui.mViewportXYZ->toggleBackground(); });
+
ui.btnOverwrite->setDefaultAction(ui.actionOverwrite);
ui.btnFilter->setDefaultAction(ui.actionFilter);
@@ -480,6 +485,7 @@ Mainframe::Mainframe() : mChangesSinceLastSave(false) {
connect(ui.actionScreenshot, &QAction::triggered, [this]() {
QImage img = ui.mViewportXYZ->grabFrameBuffer();
+ std::cout << "-- Saving screenshot to screenshot.png" << std::endl;
img.save("screenshot.png");
QApplication::clipboard()->setImage(img);
});
@@ -1000,11 +1006,11 @@ void Mainframe::readConfig() {
}
void Mainframe::initializeIcons() {
- std::string assertDir = QDir::currentPath().toStdString() + "/../assets/";
+ fs::path assetDir = fs::path(ASSETS_PATH);
std::cout << QDir::currentPath().toStdString() << std::endl;
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "brush.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "brush.png").string())));
ui.actionPaintMode->setIcon(icon);
ui.btnBrushMode->setIcon(icon);
@@ -1012,72 +1018,86 @@ void Mainframe::initializeIcons() {
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "polygon.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "polygon.png").string())));
ui.actionPolygonMode->setIcon(icon);
ui.btnPolygonMode->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "filter.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "filter.png").string())));
ui.actionFilter->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "overwrite_on.png")), QIcon::Normal, QIcon::On);
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "overwrite_off.png")), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "overwrite_on.png").string())), QIcon::Normal, QIcon::On);
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "overwrite_off.png").string())), QIcon::Normal, QIcon::Off);
ui.actionOverwrite->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "open.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "open.png").string())));
ui.actionOpen->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "save.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "save.png").string())));
ui.actionSave->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "reload.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "reload.png").string())));
ui.actionReload->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "centerview.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "centerview.png").string())));
ui.actionCenterView->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "image.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "insert_picture_icon_2.png").string())));
ui.actionShowImage->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "layoutA.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "layoutA.png").string())));
ui.btnButtonLayoutA->setIcon(icon);
}
{
QIcon icon;
- icon.addPixmap(QPixmap(QString::fromStdString(assertDir + "layoutB.png")));
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "layoutB.png").string())));
ui.btnButtonLayoutB->setIcon(icon);
}
+
+ {
+ QIcon icon;
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "dark_mode.png").string())));
+
+ ui.actionToggleDarkBackground->setIcon(icon);
+ }
+
+ {
+ QIcon icon;
+ icon.addPixmap(QPixmap(QString::fromStdString((assetDir / "camera.png").string())));
+
+ ui.actionScreenshot->setIcon(icon);
+ }
}
void Mainframe::keyPressEvent(QKeyEvent* event) {
diff --git a/src/widget/Viewport.cpp b/src/widget/Viewport.cpp
index 13b4c0d..7701132 100644
--- a/src/widget/Viewport.cpp
+++ b/src/widget/Viewport.cpp
@@ -23,6 +23,7 @@ Viewport::Viewport(QWidget* parent, Qt::WindowFlags f)
contextInitialized_(initContext()),
mAxis(XYZ),
mMode(NONE),
+ mBackground(LIGHT),
mFlags(FLAG_OVERWRITE),
mCurrentLabel(0),
mRadius(5),
@@ -561,6 +562,17 @@ void Viewport::setMode(MODE mode) {
updateGL();
}
+void Viewport::toggleBackground() {
+ if (mBackground == BACKGROUND::LIGHT)
+ {
+ mBackground = BACKGROUND::DARK;
+ } else {
+ mBackground = BACKGROUND::LIGHT;
+ }
+
+ updateGL();
+}
+
void Viewport::setFlags(int32_t flags) { mFlags = flags; }
void Viewport::setOverwrite(bool value) {
@@ -670,7 +682,7 @@ void Viewport::setLabelVisibility(uint32_t label, bool visible) {
}
void Viewport::initializeGL() {
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ applyBackground();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_LINE_SMOOTH);
@@ -678,6 +690,14 @@ void Viewport::initializeGL() {
mCamera->lookAt(5.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f);
}
+void Viewport::applyBackground() {
+ if (mBackground == LIGHT) {
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ } else {
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ }
+}
+
void Viewport::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
@@ -708,6 +728,7 @@ void Viewport::resizeGL(int w, int h) {
void Viewport::paintGL() {
glow::_CheckGlError(__FILE__, __LINE__);
+ applyBackground();
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPointSize(pointSize_);
diff --git a/src/widget/Viewport.h b/src/widget/Viewport.h
index 787cefe..7f74a0f 100644
--- a/src/widget/Viewport.h
+++ b/src/widget/Viewport.h
@@ -51,6 +51,8 @@ class Viewport : public QGLWidget {
enum MODE { NONE, PAINT, POLYGON };
+ enum BACKGROUND { LIGHT, DARK };
+
enum FLAGS { FLAG_OVERWRITE = 1, FLAG_OTHER = 2 };
enum class CameraProjection { perspective, orthographic };
@@ -142,6 +144,7 @@ class Viewport : public QGLWidget {
void setInstanceableLabels(const std::vector& labels);
void setMode(MODE mode);
+ void toggleBackground();
void setFlags(int32_t flags);
void setOverwrite(bool value);
@@ -178,6 +181,7 @@ class Viewport : public QGLWidget {
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
+ void applyBackground();
void wheelEvent(QWheelEvent*);
void mousePressEvent(QMouseEvent*);
@@ -221,6 +225,7 @@ class Viewport : public QGLWidget {
AXIS mAxis;
MODE mMode;
+ BACKGROUND mBackground;
int32_t mFlags;
uint32_t mCurrentLabel;