From 2607559d63fe9c015ebb508c7cb1f70a6b35266a Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Fri, 6 Jul 2018 23:41:01 +0200 Subject: [PATCH] Add some utility functions for working with .flo files. --- Makefile | 8 +++++++- eval.cpp | 29 +++++++++++++++++++++++++++++ flow.cpp | 2 +- util.cpp | 26 ++++++++++++++++++++++++++ flow2rgb.h => util.h | 19 +++++++++++++++---- vis.cpp | 36 ++++++++++++++++++++++++++++++++++++ 6 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 eval.cpp create mode 100644 util.cpp rename flow2rgb.h => util.h (81%) create mode 100644 vis.cpp diff --git a/Makefile b/Makefile index beebb67..609128b 100644 --- a/Makefile +++ b/Makefile @@ -25,12 +25,18 @@ OBJS += ffmpeg_raii.o main.o player.o %.moc.cpp: %.h moc $< -o $@ -all: futatabi +all: futatabi flow vis eval mainwindow.o: ui_mainwindow.h futatabi: $(OBJS) $(CEF_LIBS) $(CXX) -o $@ $^ $(LDFLAGS) $(LDLIBS) +flow: flow.o + $(CXX) -o $@ $^ -lepoxy -lSDL2 +eval: eval.o util.o + $(CXX) -o $@ $^ +vis: vis.o util.o + $(CXX) -o $@ $^ DEPS=$(OBJS:.o=.d) -include $(DEPS) diff --git a/eval.cpp b/eval.cpp new file mode 100644 index 0000000..e19ce1f --- /dev/null +++ b/eval.cpp @@ -0,0 +1,29 @@ +// Evaluate a .flo file against ground truth, +// outputting the average end-point error. + +#include +#include + +#include + +#include "util.h" + +using namespace std; + +int main(int argc, char **argv) +{ + Flow flow = read_flow(argv[1]); + Flow gt = read_flow(argv[2]); + + double sum = 0.0; + for (unsigned y = 0; y < unsigned(flow.height); ++y) { + for (unsigned x = 0; x < unsigned(flow.width); ++x) { + float du = flow.flow[y * flow.width + x].du; + float dv = flow.flow[y * flow.width + x].dv; + float gt_du = gt.flow[y * flow.width + x].du; + float gt_dv = gt.flow[y * flow.width + x].dv; + sum += hypot(du - gt_du, dv - gt_dv); + } + } + fprintf(stderr, "Average EPE: %.2f pixels\n", sum / (flow.width * flow.height)); +} diff --git a/flow.cpp b/flow.cpp index 43daa78..1bac955 100644 --- a/flow.cpp +++ b/flow.cpp @@ -16,7 +16,7 @@ #include #include -#include "flow2rgb.h" +#include "util.h" #include #include diff --git a/util.cpp b/util.cpp new file mode 100644 index 0000000..3701d62 --- /dev/null +++ b/util.cpp @@ -0,0 +1,26 @@ +#include +#include + +#include + +#include "util.h" + +using namespace std; + +Flow read_flow(const char *filename) +{ + FILE *flowfp = fopen(filename, "rb"); + uint32_t hdr, width, height; + fread(&hdr, sizeof(hdr), 1, flowfp); + fread(&width, sizeof(width), 1, flowfp); + fread(&height, sizeof(height), 1, flowfp); + + unique_ptr flow(new Vec2[width * height]); + fread(flow.get(), width * height * sizeof(Vec2), 1, flowfp); + + Flow ret; + ret.width = width; + ret.height = height; + ret.flow = move(flow); + return ret; +} diff --git a/flow2rgb.h b/util.h similarity index 81% rename from flow2rgb.h rename to util.h index ca17530..3693fd2 100644 --- a/flow2rgb.h +++ b/util.h @@ -1,10 +1,21 @@ -#ifndef _FLOW2RGB_H -#define _FLOW2RGB_H 1 +#ifndef _UTIL_H +#define _UTIL_H 1 #include #include - #include +#include + +struct Vec2 { + float du, dv; +}; + +struct Flow { + uint32_t width, height; + std::unique_ptr flow; +}; + +Flow read_flow(const char *filename); // du and dv are in pixels. inline void flow2rgb(float du, float dv, uint8_t *rr, uint8_t *gg, uint8_t *bb) @@ -42,4 +53,4 @@ inline void flow2rgb(float du, float dv, uint8_t *rr, uint8_t *gg, uint8_t *bb) *bb = lrintf(b * 255.0f); } -#endif // !defined(_FLOW2RGB_H) +#endif // !defined(_UTIL_H) diff --git a/vis.cpp b/vis.cpp new file mode 100644 index 0000000..8ecf297 --- /dev/null +++ b/vis.cpp @@ -0,0 +1,36 @@ +// Visualize a .flo file. + +#include +#include + +#include + +#include "util.h" + +using namespace std; + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: ./vis input.flo out.ppm\n"); + exit(1); + } + + Flow flow = read_flow(argv[1]); + + FILE *fp = fopen(argv[2], "wb"); + fprintf(fp, "P6\n%d %d\n255\n", flow.width, flow.height); + for (unsigned y = 0; y < unsigned(flow.height); ++y) { + for (unsigned x = 0; x < unsigned(flow.width); ++x) { + float du = flow.flow[y * flow.width + x].du; + float dv = flow.flow[y * flow.width + x].dv; + + uint8_t r, g, b; + flow2rgb(du, dv, &r, &g, &b); + putc(r, fp); + putc(g, fp); + putc(b, fp); + } + } + fclose(fp); +} -- 2.39.2