aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-08-17 08:56:06 -0400
committerYour Name <you@example.com>2021-08-17 08:56:06 -0400
commit8a6b5564c0fc37e6e556d04e17ddba86d4bd3dc1 (patch)
tree238d013eb3cfe2dc170a52dec3bfcd72a1e468ca
parent8c884838ced928d29a8436be8b2808766c5a1e53 (diff)
downloadannotator-8a6b5564c0fc37e6e556d04e17ddba86d4bd3dc1.tar.gz
annotator-8a6b5564c0fc37e6e556d04e17ddba86d4bd3dc1.tar.bz2
annotator-8a6b5564c0fc37e6e556d04e17ddba86d4bd3dc1.zip
Started work on bounding boxes
-rw-r--r--Makefile2
-rw-r--r--annotator.conf1
-rw-r--r--src/labeller.cc6
-rw-r--r--src/labeller.h6
-rw-r--r--src/settings.cc19
-rw-r--r--src/settings.h1
-rw-r--r--src/ui.cc28
7 files changed, 57 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index 8cc7873..9e1db82 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CC=g++
LIBS=libconfuse opencv4
CFLAGS=-c -Wall -fPIC -std=c++20
-LDFLAGS=-pthread
+LDFLAGS=
SOURCES=src/annotator.cc src/labeller.cc src/playback.cc src/settings.cc src/ui.cc
OBJECTS=$(SOURCES:.cc=.o)
LIBRARY=
diff --git a/annotator.conf b/annotator.conf
index d89676d..6ec3ff2 100644
--- a/annotator.conf
+++ b/annotator.conf
@@ -1 +1,2 @@
labels = {"saccade", "blink", "head move start", "head move end", "look down start", "look down end"}
+rectangles = {"face"}
diff --git a/src/labeller.cc b/src/labeller.cc
index 64da2d7..024b720 100644
--- a/src/labeller.cc
+++ b/src/labeller.cc
@@ -6,6 +6,7 @@
namespace backend {
struct labeller_impl {
std::vector<std::string> labels;
+ std::vector<std::string> rectangleLabels;
std::vector<label> annotations;
// Bool in undo/redo buffers is whether was applied or deleted
std::vector<std::pair<bool, label>> undoBuffer;
@@ -16,6 +17,7 @@ namespace backend {
labeller::labeller(const std::filesystem::path& savepath) {
data = std::shared_ptr<labeller_impl>(new labeller_impl);
data->labels = settings::getLabels();
+ data->rectangleLabels = settings::getRectangleLabels();
data->savepath = savepath;
}
@@ -39,6 +41,10 @@ namespace backend {
return data->labels;
}
+ std::vector<std::string> labeller::getRectangleLabels() const {
+ return data->rectangleLabels;
+ }
+
void appLab(std::vector<label>& annotations, label lab) {
annotations.push_back(lab);
}
diff --git a/src/labeller.h b/src/labeller.h
index 4248e2a..e0dc090 100644
--- a/src/labeller.h
+++ b/src/labeller.h
@@ -8,11 +8,16 @@
namespace backend {
struct labeller_impl;
+ struct rect {
+ int x1=0, x2=0, y1=0, y2=0;
+ };
+
struct label {
label() {}
label(const std::string& name, double time) : name(name), time(time) {}
std::string name;
double time;
+ rect location;
};
class labeller {
@@ -20,6 +25,7 @@ namespace backend {
labeller(const std::filesystem::path& savepath);
std::pair<label, label> getSurrounding(double time) const;
std::vector<std::string> getLabels() const;
+ std::vector<std::string> getRectangleLabels() const;
void applyLabel(std::string name, double time);
void deleteLabel(double time); // Deletes closest to time, last added if ties
void undo();
diff --git a/src/settings.cc b/src/settings.cc
index d19acde..7004e1d 100644
--- a/src/settings.cc
+++ b/src/settings.cc
@@ -5,9 +5,9 @@
#include <stdexcept>
namespace settings {
- std::vector<std::string> getLabels() {
+ std::vector<std::string> readVector(std::string heading) {
cfg_opt_t opts[] = {
- CFG_STR_LIST("labels", NULL, CFGF_NONE),
+ CFG_STR_LIST(heading.c_str(), NULL, CFGF_NONE),
CFG_END()
};
cfg_t *cfg = cfg_init(opts, CFGF_IGNORE_UNKNOWN);
@@ -17,12 +17,21 @@ namespace settings {
try {
std::vector<std::string> ret;
std::size_t i;
- for(i = 0; i < cfg_size(cfg, "labels"); i++) {
- ret.push_back(cfg_getnstr(cfg, "labels", i));
+ for(i = 0; i < cfg_size(cfg, heading.c_str()); i++) {
+ ret.push_back(cfg_getnstr(cfg, heading.c_str(), i));
}
return ret;
} catch(std::exception& e) {
- throw std::runtime_error("Cannot find 'labels' in configuration file");
+ throw std::runtime_error("Cannot find '" + heading + "' in configuration file");
}
}
+
+ std::vector<std::string> getLabels() {
+ return readVector("labels");
+ }
+
+ std::vector<std::string> getRectangleLabels() {
+ return readVector("rectangles");
+ }
}
+
diff --git a/src/settings.h b/src/settings.h
index 3b3ad71..2aa93ae 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -4,4 +4,5 @@
namespace settings {
std::vector<std::string> getLabels(void);
+ std::vector<std::string> getRectangleLabels(void);
}
diff --git a/src/ui.cc b/src/ui.cc
index 3d0e193..858d74c 100644
--- a/src/ui.cc
+++ b/src/ui.cc
@@ -73,6 +73,32 @@ namespace frontend {
return false;
}
+ void mouseCallback(int event, int x, int y, int flags, void* userdata) {
+ // userdata is actually a &shared_ptr<ui_impl>
+ shared_ptr<ui_impl> data = (shared_ptr<ui_impl>) *userdata;
+ static bool mouseDown = false;
+ // We're interested in left button down/up and movement when down
+ if(event == cv::EVENT_LBUTTONDOWN) {
+ // If the current frame doesn't have a rectangle label, then make one
+ mouseDown = true;
+ double time = data->pb->getTime()
+ auto labs = data->llr->getSurrounding(time);
+ backend::label current;
+ if(labs.first.time == time) {
+ current = labs.first;
+ } else if(labs.second.time == time) {
+ current = labs.second;
+ } else {
+
+ }
+ } else if(event == cv::EVENT_LBUTTONUP) {
+ // Mouse is no longer down
+ mouseDown = false;
+ } else if(event == cv::EVENT_MOUSEMOVE) {
+ // If the mouse is down, update x2 and y2 of current window
+ }
+ }
+
void ui::begin() {
std::cout << "Playing a video that's " << data->pb->getMaxFrame() << " frames (" << data->pb->getMaxTime() << " seconds) long." << std::endl;
std::cout << "Annotations:" << std::endl;
@@ -84,6 +110,8 @@ namespace frontend {
struct winsize size;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
int cols = size.ws_col;
+ // Register mouse callback
+ cv::setMouseCallback("Video", mouseCallback, &data);
while(true) {
data->pb->display("Video");
data->pb->interFrameSleep();