#include <assert.h>
#include <stdio.h>
+#include "flow2rgb.h"
+
#include <algorithm>
#include <memory>
glBindTextureUnit(0, tex0_view);
glBindSampler(0, nearest_sampler);
glProgramUniform1i(sobel_program, glGetUniformLocation(sobel_program, "tex"), 0);
- glProgramUniform1f(sobel_program, glGetUniformLocation(sobel_program, "inv_width"), 1.0f / level_width);
- glProgramUniform1f(sobel_program, glGetUniformLocation(sobel_program, "inv_height"), 1.0f / level_height);
+ glProgramUniform2f(sobel_program, glGetUniformLocation(sobel_program, "image_size"), level_width, level_height);
+ glProgramUniform2f(sobel_program, glGetUniformLocation(sobel_program, "inv_image_size"), 1.0f / level_width, 1.0f / level_height);
GLuint grad0_fbo; // TODO: cleanup
glCreateFramebuffers(1, &grad0_fbo);
bind_sampler(motion_search_program, "grad0_tex", 2, grad0_tex, nearest_sampler);
bind_sampler(motion_search_program, "flow_tex", 3, flow_tex, linear_sampler);
- glProgramUniform1f(motion_search_program, glGetUniformLocation(motion_search_program, "image_width"), level_width);
- glProgramUniform1f(motion_search_program, glGetUniformLocation(motion_search_program, "image_height"), level_height);
- glProgramUniform1f(motion_search_program, glGetUniformLocation(motion_search_program, "inv_image_width"), 1.0f / level_width);
- glProgramUniform1f(motion_search_program, glGetUniformLocation(motion_search_program, "inv_image_height"), 1.0f / level_height);
+ glProgramUniform2f(motion_search_program, glGetUniformLocation(motion_search_program, "image_size"), level_width, level_height);
+ glProgramUniform2f(motion_search_program, glGetUniformLocation(motion_search_program, "inv_image_size"), 1.0f / level_width, 1.0f / level_height);
GLuint flow_fbo; // TODO: cleanup
glCreateFramebuffers(1, &flow_fbo);
MotionSearch motion_search;
Densify densify;
+ GLuint query;
+ glGenQueries(1, &query);
+ glBeginQuery(GL_TIME_ELAPSED, query);
+
for (int level = coarsest_level; level >= int(finest_level); --level) {
int level_width = WIDTH >> level;
int level_height = HEIGHT >> level;
// Densification.
- // Set up an output texture.
+ // Set up an output texture (initially zero).
GLuint dense_flow_tex;
glCreateTextures(GL_TEXTURE_2D, 1, &dense_flow_tex);
//glTextureStorage2D(dense_flow_tex, 1, GL_RGB16F, level_width, level_height);
prev_level_flow_tex = dense_flow_tex;
}
+ glEndQuery(GL_TIME_ELAPSED);
+
+ GLint available;
+ do {
+ glGetQueryObjectiv(query, GL_QUERY_RESULT_AVAILABLE, &available);
+ } while (!available);
+ GLuint64 time_elapsed;
+ glGetQueryObjectui64v(query, GL_QUERY_RESULT, &time_elapsed);
+ fprintf(stderr, "GPU time used = %.1f ms\n", time_elapsed / 1e6);
int level_width = WIDTH >> finest_level;
int level_height = HEIGHT >> finest_level;
glGetTextureImage(prev_level_flow_tex, 0, GL_RGB, GL_FLOAT, level_width * level_height * 3 * sizeof(float), dense_flow.get());
FILE *fp = fopen("flow.ppm", "wb");
+ FILE *flowfp = fopen("flow.flo", "wb");
fprintf(fp, "P6\n%d %d\n255\n", level_width, level_height);
+ fprintf(flowfp, "FEIH");
+ fwrite(&level_width, 4, 1, flowfp);
+ fwrite(&level_height, 4, 1, flowfp);
for (unsigned y = 0; y < unsigned(level_height); ++y) {
int yy = level_height - y - 1;
for (unsigned x = 0; x < unsigned(level_width); ++x) {
float dv = dense_flow[(yy * level_width + x) * 3 + 1];
float w = dense_flow[(yy * level_width + x) * 3 + 2];
- du /= w;
- dv /= w;
-
- float angle = atan2(dv * level_width, du * level_height);
- float magnitude = min(hypot(du * level_width, dv * level_height) / 20.0, 1.0);
-
- // HSV to RGB (from Wikipedia). Saturation is 1.
- float c = magnitude;
- float h = (angle + M_PI) * 6.0 / (2.0 * M_PI);
- float X = c * (1.0 - fabs(fmod(h, 2.0) - 1.0));
- float r = 0.0f, g = 0.0f, b = 0.0f;
- if (h < 1.0f) {
- r = c; g = X;
- } else if (h < 2.0f) {
- r = X; g = c;
- } else if (h < 3.0f) {
- g = c; b = X;
- } else if (h < 4.0f) {
- g = X; b = c;
- } else if (h < 5.0f) {
- r = X; b = c;
- } else if (h < 6.0f) {
- r = c; b = X;
- } else {
- // h is NaN, so black is fine.
- }
- float m = magnitude - c;
- r += m; g += m; b += m;
- r = max(min(r, 1.0f), 0.0f);
- g = max(min(g, 1.0f), 0.0f);
- b = max(min(b, 1.0f), 0.0f);
- putc(lrintf(r * 255.0f), fp);
- putc(lrintf(g * 255.0f), fp);
- putc(lrintf(b * 255.0f), fp);
+ du = (du / w) * level_width;
+ dv = (-dv / w) * level_height;
+
+ fwrite(&du, 4, 1, flowfp);
+ fwrite(&dv, 4, 1, flowfp);
+
+ uint8_t r, g, b;
+ flow2rgb(du, dv, &r, &g, &b);
+ putc(r, fp);
+ putc(g, fp);
+ putc(b, fp);
}
}
fclose(fp);
+ fclose(flowfp);
fprintf(stderr, "err = %d\n", glGetError());
}