aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-08-17 12:38:14 -0400
committerYour Name <you@example.com>2021-08-17 12:38:14 -0400
commitab5e941dcaedcf2cc896eed1ea257c59780fdb59 (patch)
tree503284d6999fb92f86bbf39385e17e9b7d8bd8fa
parent2a4ca022ad37ff2452ec3addb8c760a93bb616c6 (diff)
downloadannotator-ab5e941dcaedcf2cc896eed1ea257c59780fdb59.tar.gz
annotator-ab5e941dcaedcf2cc896eed1ea257c59780fdb59.tar.bz2
annotator-ab5e941dcaedcf2cc896eed1ea257c59780fdb59.zip
Implemented parts of mouse click event
-rw-r--r--src/labeller.cc5
-rw-r--r--src/labeller.h4
-rw-r--r--src/playback.cc8
-rw-r--r--src/playback.h6
-rw-r--r--src/ui.cc48
5 files changed, 57 insertions, 14 deletions
diff --git a/src/labeller.cc b/src/labeller.cc
index f7fa69e..ea72db0 100644
--- a/src/labeller.cc
+++ b/src/labeller.cc
@@ -54,6 +54,11 @@ namespace backend {
return labs;
}
+ std::vector<label>& labeller::getEditableLabels() {
+ return data->annotations;
+ }
+
+
std::vector<std::string> labeller::getLabels() const {
return data->labels;
}
diff --git a/src/labeller.h b/src/labeller.h
index e0dc090..cf108f5 100644
--- a/src/labeller.h
+++ b/src/labeller.h
@@ -10,6 +10,9 @@ namespace backend {
struct rect {
int x1=0, x2=0, y1=0, y2=0;
+ bool nonzero() const {
+ return (x1 != 0 || x1 != 0 || y1 != 0 || y2 != 0);
+ }
};
struct label {
@@ -24,6 +27,7 @@ namespace backend {
public:
labeller(const std::filesystem::path& savepath);
std::pair<label, label> getSurrounding(double time) const;
+ std::vector<label>& getEditableLabels();
std::vector<std::string> getLabels() const;
std::vector<std::string> getRectangleLabels() const;
void applyLabel(std::string name, double time);
diff --git a/src/playback.cc b/src/playback.cc
index 8839528..bbc2649 100644
--- a/src/playback.cc
+++ b/src/playback.cc
@@ -1,4 +1,5 @@
#include "playback.h"
+#include "labeller.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include <stdexcept>
@@ -31,7 +32,12 @@ namespace frontend {
cap.release();
}
- void playback::display(const std::string& windowName) const {
+ void playback::display(const std::string& windowName, const backend::rect &r) const {
+ cv::Mat curr(data->images[data->frameNum]);
+ if(r.nonzero()) {
+ // Update with the rectangle
+ cv::rectangle(curr, cv::Point(r.x1, r.y1), cv::Point(r.x2, r.y2), cv::Scalar(255, 0, 0), 2, cv::LINE_8);
+ }
cv::imshow(windowName, data->images[data->frameNum]);
}
diff --git a/src/playback.h b/src/playback.h
index 2fd5fa9..3f6e67f 100644
--- a/src/playback.h
+++ b/src/playback.h
@@ -3,12 +3,16 @@
#include <memory>
#include <string>
+namespace backend {
+ struct rect;
+}
+
namespace frontend {
struct playback_impl;
class playback {
public:
playback(const std::filesystem::path& video, std::size_t frameCap=0);
- void display(const std::string& windowName) const;
+ void display(const std::string& windowName, const backend::rect &r) const;
bool seekFrame(std::size_t frameNum);
std::size_t getFrame() const;
bool seekTime(double time);
diff --git a/src/ui.cc b/src/ui.cc
index f852bde..9b24815 100644
--- a/src/ui.cc
+++ b/src/ui.cc
@@ -73,29 +73,52 @@ namespace frontend {
return false;
}
+ backend::label* getCurrentRectLabel(ui_impl *data) {
+ auto labs = data->llr->getEditableLabels();
+ for(auto rit = labs.rbegin(); rit != labs.rend(); rit++) {
+ if(rit->location.nonzero()) {
+ return &(*rit);
+ }
+ }
+ return nullptr;
+ }
+
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;
+ auto data = static_cast<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 {
-
+ double time = data->pb->getTime();
+ auto lab = getCurrentRectLabel(data);
+ if(lab && lab->time == time) {
+ // Use this one
+ } else { // Make one
+ // Try to use the first rectangle annotation, fall back on normal, then "Rectangle"
+ std::string name = "Rectangle";
+ if(!data->llr->getRectangleLabels().empty()) {
+ name = data->llr->getRectangleLabels()[0];
+ } else if(!data->llr->getLabels().empty()) {
+ name = data->llr->getLabels()[0];
+ }
+ data->llr->applyLabel(name, time);
+ lab = &data->llr->getEditableLabels().back();
}
+ lab->location.x1 = x;
+ lab->location.y1 = y;
} 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
+ if(mouseDown) {
+ auto lab = getCurrentRectLabel(data); // It will be valid! TODO: Will it?
+ std::cout << "Updating location from " << lab->location.x2 << ", " << lab->location.y2 << " to " << x << ", " << y << "\n";
+ lab->location.x2 = x;
+ lab->location.y2 = y;
+ }
}
}
@@ -111,9 +134,10 @@ namespace frontend {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
int cols = size.ws_col;
// Register mouse callback
- cv::setMouseCallback("Video", mouseCallback, &data);
+ data->pb->display("Video", (getCurrentRectLabel(data.get()))? getCurrentRectLabel(data.get())->location : backend::rect());
+ cv::setMouseCallback("Video", mouseCallback, data.get());
while(true) {
- data->pb->display("Video");
+ data->pb->display("Video", (getCurrentRectLabel(data.get()))? getCurrentRectLabel(data.get())->location : backend::rect());
data->pb->interFrameSleep();
if(handleKey(cv::pollKey(), data)) {
break;