reworked namespaces

pull/3471/head
kallaballa 2 years ago
parent e6f59870bc
commit 9a92c42425
  1. 2
      Makefile
  2. 4
      src/common/Makefile
  3. 12
      src/common/detail/clglcontext.cpp
  4. 14
      src/common/detail/clglcontext.hpp
  5. 9
      src/common/detail/clvacontext.cpp
  6. 9
      src/common/detail/clvacontext.hpp
  7. 15
      src/common/detail/nanovgcontext.cpp
  8. 11
      src/common/detail/nanovgcontext.hpp
  9. 599
      src/common/nvg.cpp
  10. 208
      src/common/nvg.hpp
  11. 38
      src/common/util.cpp
  12. 13
      src/common/util.hpp
  13. 102
      src/common/viz2d.cpp
  14. 32
      src/common/viz2d.hpp
  15. 83
      src/optflow/optflow-demo.cpp
  16. 8
      src/video/video-demo.cpp

@ -1,7 +1,7 @@
CXX := g++
CXXFLAGS := -std=c++20 -pthread -fno-strict-aliasing -pedantic -Wall -flto -I/usr/local/include/opencv4/ -I/usr/local/include/nanovg
LDFLAGS := -L/opt/local/lib -flto -L/usr/local/lib64 -L../common/
LIBS := -lnanogui -lopencv_viz2d
LIBS := -lnanogui -lviz2d
.PHONY: all release debian-release info debug asan clean debian-clean distclean
DESTDIR := /
PREFIX := /usr/local

@ -1,6 +1,6 @@
TARGET := libopencv_viz2d.so
TARGET := libviz2d.so
SRCS := clglcontext.cpp clvacontext.cpp nanovgcontext.cpp viz2d.cpp util.cpp
SRCS := detail/clglcontext.cpp detail/clvacontext.cpp detail/nanovgcontext.cpp viz2d.cpp util.cpp nvg.cpp
#precompiled headers
HEADERS :=

@ -1,8 +1,11 @@
#include "clglcontext.hpp"
#include "util.hpp"
#include "viz2d.hpp"
#include "../util.hpp"
#include "../viz2d.hpp"
namespace kb {
namespace viz2d {
namespace detail {
//FIXME use cv::ogl
CLGLContext::CLGLContext(const cv::Size& frameBufferSize) :
frameBufferSize_(frameBufferSize) {
@ -96,5 +99,6 @@ void CLGLContext::releaseToGL(cv::UMat &m) {
cv::flip(m, m, 0);
GL_CHECK(cv::ogl::convertToGLTexture2D(m, getTexture2D()));
}
} /* namespace kb */
}
}
}

@ -12,16 +12,20 @@
#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>
#include "util.hpp"
#include "../util.hpp"
namespace kb {
namespace kb {
namespace viz2d {
class Viz2D;
namespace detail {
typedef cv::ocl::OpenCLExecutionContext CLExecContext_t;
typedef cv::ocl::OpenCLExecutionContextScope CLExecScope_t;
class CLGLContext {
friend class CLVAContext;
friend class NanoVGContext;
friend class Viz2D;
friend class kb::viz2d::Viz2D;
cv::ogl::Texture2D *frameBufferTex_;
GLuint frameBufferID;
GLuint renderBufferID;
@ -69,6 +73,8 @@ protected:
void releaseToGL(cv::UMat &m);
cv::UMat frameBuffer_;
};
} /* namespace kb */
}
}
}
#endif /* SRC_COMMON_CLGLCONTEXT_HPP_ */

@ -1,8 +1,10 @@
#include "clvacontext.hpp"
#include "viz2d.hpp"
#include "../viz2d.hpp"
namespace kb {
namespace viz2d {
namespace detail {
CLVAContext::CLVAContext(CLGLContext &clglContext) :
clglContext_(clglContext) {
@ -17,7 +19,6 @@ void CLVAContext::setVideoFrameSize(const cv::Size& sz) {
cv::Size CLVAContext::getVideoFrameSize() {
assert(videoFrameSize_ == cv::Size(0,0) || "Video frame size not initialized");
return videoFrameSize_;
}
@ -71,4 +72,6 @@ void CLVAContext::copyContext() {
CLExecContext_t CLVAContext::getCLExecContext() {
return context_;
}
} /* namespace kb */
}
}
}

@ -2,13 +2,14 @@
#define SRC_COMMON_CLVACONTEXT_HPP_
#include "clglcontext.hpp"
#include "util.hpp"
namespace kb {
namespace viz2d {
class Viz2D;
namespace detail {
class CLVAContext {
friend class Viz2D;
friend class kb::viz2d::Viz2D;
CLExecContext_t context_;
CLGLContext &clglContext_;
cv::UMat frameBuffer_;
@ -29,6 +30,8 @@ public:
bool hasContext();
void copyContext();
};
} /* namespace kb */
}
}
}
#endif /* SRC_COMMON_CLVACONTEXT_HPP_ */

@ -1,9 +1,10 @@
#include "nanovgcontext.hpp"
#include "viz2d.hpp"
#include "../viz2d.hpp"
namespace kb {
namespace viz2d {
namespace detail {
NanoVGContext::NanoVGContext(Viz2D &v2d, NVGcontext *context, CLGLContext &fbContext) :
v2d_(v2d), context_(context), clglContext_(fbContext) {
nvgCreateFont(context_, "libertine", "assets/LinLibertine_RB.ttf");
@ -13,11 +14,12 @@ NanoVGContext::NanoVGContext(Viz2D &v2d, NVGcontext *context, CLGLContext &fbCon
CLGLContext::FrameBufferScope fbScope(clglContext_, tmp);
}
void NanoVGContext::render(std::function<void(NVGcontext*, const cv::Size&)> fn) {
void NanoVGContext::render(std::function<void(const cv::Size&)> fn) {
CLExecScope_t scope(clglContext_.getCLExecContext());
CLGLContext::GLScope glScope(clglContext_);
NanoVGContext::Scope nvgScope(*this);
fn(context_, clglContext_.getSize());
kb::nvg::detail::set_current_context(context_),
fn(clglContext_.getSize());
}
void NanoVGContext::begin() {
@ -31,7 +33,10 @@ void NanoVGContext::begin() {
}
void NanoVGContext::end() {
//FIXME make nvgCancelFrame possible
nvgEndFrame(context_);
nvgRestore(context_);
}
} /* namespace kb */
}
}
}

@ -5,9 +5,12 @@
#include "clglcontext.hpp"
#include <nanogui/nanogui.h>
#include <nanogui/opengl.h>
#include "util.hpp"
#include "../util.hpp"
#include "../nvg.hpp"
namespace kb {
namespace viz2d {
namespace detail {
class NanoVGContext {
Viz2D& v2d_;
NVGcontext *context_;
@ -25,11 +28,13 @@ public:
}
};
NanoVGContext(Viz2D& v2d, NVGcontext *context, CLGLContext &fbContext);
void render(std::function<void(NVGcontext*, const cv::Size&)> fn);
void render(std::function<void(const cv::Size&)> fn);
private:
void begin();
void end();
};
} /* namespace kb */
}
}
}
#endif /* SRC_COMMON_NANOVGCONTEXT_HPP_ */

@ -0,0 +1,599 @@
#include "nvg.hpp"
namespace kb {
namespace nvg {
namespace detail {
class NVG;
void set_current_context(NVGcontext* ctx) {
if(nvg_instance != nullptr)
delete nvg_instance;
nvg_instance = new NVG(ctx);
}
NVG* get_current_context() {
assert(nvg_instance != nullptr);
return nvg_instance;
}
int NVG::createFont(const char* name, const char* filename) {
return nvgCreateFont(getContext(), name, filename);
}
int NVG::createFontMem(const char* name, unsigned char* data, int ndata, int freeData) {
return nvgCreateFontMem(getContext(), name, data, ndata, freeData);
}
int NVG::findFont(const char* name) {
return nvgFindFont(getContext(), name);
}
int NVG::addFallbackFontId(int baseFont, int fallbackFont) {
return nvgAddFallbackFontId(getContext(), baseFont, fallbackFont);
}
int NVG::addFallbackFont(const char* baseFont, const char* fallbackFont) {
return nvgAddFallbackFont(getContext(), baseFont, fallbackFont);
}
void NVG::fontSize(float size) {
nvgFontSize(getContext(), size);
}
void NVG::fontBlur(float blur) {
nvgFontBlur(getContext(), blur);
}
void NVG::textLetterSpacing(float spacing) {
nvgTextLetterSpacing(getContext(), spacing);
}
void NVG::textLineHeight(float lineHeight) {
nvgTextLineHeight(getContext(), lineHeight);
}
void NVG::textAlign(int align) {
nvgTextAlign(getContext(), align);
}
void NVG::fontFaceId(int font) {
nvgFontFaceId(getContext(), font);
}
void NVG::fontFace(const char* font) {
nvgFontFace(getContext(), font);
}
float NVG::text(float x, float y, const char* string, const char* end) {
return nvgText(getContext(), x, y, string, end);
}
void NVG::textBox(float x, float y, float breakRowWidth, const char* string, const char* end) {
nvgTextBox(getContext(), x, y, breakRowWidth, string, end);
}
float NVG::textBounds(float x, float y, const char* string, const char* end, float* bounds) {
return nvgTextBounds(getContext(), x, y, string, end, bounds);
}
void NVG::textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds) {
nvgTextBoxBounds(getContext(), x, y, breakRowWidth, string, end, bounds);
}
int NVG::textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition* positions, int maxPositions) {
std::vector<NVGglyphPosition> gp(maxPositions);
int result = nvgTextGlyphPositions(getContext(), x, y, string, end, gp.data(), maxPositions);
for(int i = 0; i < maxPositions; ++i) {
positions[i].str = gp[i].str;
positions[i].x = gp[i].x;
positions[i].minx = gp[i].minx;
positions[i].maxx = gp[i].maxx;
}
return result;
}
void NVG::textMetrics(float* ascender, float* descender, float* lineh) {
nvgTextMetrics(getContext(), ascender, descender, lineh);
}
int NVG::textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow* rows, int maxRows) {
NVGtextRow tr[maxRows];
int result = nvgTextBreakLines(getContext(),string, end, breakRowWidth, tr, maxRows);
for(int i = 0; i < maxRows; ++i) {
rows[i].start = tr[i].start;
rows[i].end = tr[i].end;
rows[i].next = tr[i].next;
rows[i].width = tr[i].width;
rows[i].minx = tr[i].minx;
rows[i].maxx = tr[i].maxx;
}
return result;
}
void NVG::save() {
nvgSave(getContext());
}
void NVG::restore() {
nvgRestore(getContext());
}
void NVG::reset() {
nvgReset(getContext());
}
void NVG::shapeAntiAlias(int enabled) {
nvgShapeAntiAlias(getContext(), enabled);
}
void NVG::strokeColor(const cv::Scalar& bgra) {
nvgStrokeColor(getContext(), nvgRGBA(bgra[2],bgra[1],bgra[0],bgra[3]));
}
void NVG::strokePaint(Paint paint) {
NVGpaint np;
memcpy(paint.xform, np.xform, 6);
memcpy(paint.extent, np.extent, 2);
np.radius = paint.radius;
np.feather = paint.feather;
np.innerColor = nvgRGBA(paint.innerColor[2],paint.innerColor[1],paint.innerColor[0],paint.innerColor[3]);
np.outerColor = nvgRGBA(paint.outerColor[2],paint.outerColor[1],paint.outerColor[0],paint.outerColor[3]);;
np.image = paint.image;
nvgStrokePaint(getContext(), np);
}
void NVG::fillColor(const cv::Scalar& bgra) {
nvgFillColor(getContext(), nvgRGBA(bgra[2],bgra[1],bgra[0],bgra[3]));
}
void NVG::fillPaint(Paint paint) {
NVGpaint np;
memcpy(paint.xform, np.xform, 6);
memcpy(paint.extent, np.extent, 2);
np.radius = paint.radius;
np.feather = paint.feather;
np.innerColor = nvgRGBA(paint.innerColor[2],paint.innerColor[1],paint.innerColor[0],paint.innerColor[3]);
np.outerColor = nvgRGBA(paint.outerColor[2],paint.outerColor[1],paint.outerColor[0],paint.outerColor[3]);;
np.image = paint.image;
nvgFillPaint(getContext(), np);
}
void NVG::miterLimit(float limit) {
nvgMiterLimit(getContext(), limit);
}
void NVG::strokeWidth(float size) {
nvgStrokeWidth(getContext(), size);
}
void NVG::lineCap(int cap) {
nvgLineCap(getContext(), cap);
}
void NVG::lineJoin(int join) {
nvgLineJoin(getContext(), join);
}
void NVG::globalAlpha(float alpha) {
nvgGlobalAlpha(getContext(), alpha);
}
void NVG::resetTransform() {
nvgResetTransform(getContext());
}
void NVG::transform(float a, float b, float c, float d, float e, float f) {
nvgTransform(getContext(), a, b, c, d, e, f);
}
void NVG::translate(float x, float y) {
nvgTranslate(getContext(), x, y);
}
void NVG::rotate(float angle) {
nvgRotate(getContext(), angle);
}
void NVG::skewX(float angle) {
nvgSkewX(getContext(), angle);
}
void NVG::skewY(float angle) {
nvgSkewY(getContext(), angle);
}
void NVG::scale(float x, float y) {
nvgScale(getContext(), x, y);
}
void NVG::currentTransform(float* xform) {
nvgCurrentTransform(getContext(), xform);
}
void NVG::transformIdentity(float* dst) {
nvgTransformIdentity(dst);
}
void NVG::transformTranslate(float* dst, float tx, float ty) {
nvgTransformTranslate(dst, tx, ty);
}
void NVG::transformScale(float* dst, float sx, float sy) {
nvgTransformScale(dst, sx, sy);
}
void NVG::transformRotate(float* dst, float a) {
nvgTransformRotate(dst, a);
}
void NVG::transformSkewX(float* dst, float a) {
nvgTransformSkewX(dst, a);
}
void NVG::transformSkewY(float* dst, float a) {
nvgTransformSkewY(dst, a);
}
void NVG::transformMultiply(float* dst, const float* src) {
nvgTransformMultiply(dst, src);
}
void NVG::transformPremultiply(float* dst, const float* src) {
nvgTransformPremultiply(dst, src);
}
int NVG::transformInverse(float* dst, const float* src) {
return nvgTransformInverse(dst, src);
}
void NVG::transformPoint(float* dstx, float* dsty, const float* xform, float srcx, float srcy) {
nvgTransformPoint(dstx, dsty, xform, srcx, srcy);
}
float NVG::degToRad(float deg) {
return nvgDegToRad(deg);
}
float NVG::radToDeg(float rad) {
return nvgRadToDeg(rad);
}
void NVG::beginPath() {
nvgBeginPath(getContext());
}
void NVG::moveTo(float x, float y) {
nvgMoveTo(getContext(), x, y);
}
void NVG::lineTo(float x, float y) {
nvgLineTo(getContext(), x, y);
}
void NVG::bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
nvgBezierTo(getContext(), c1x, c1y, c2x, c2y, x, y);
}
void NVG::quadTo(float cx, float cy, float x, float y) {
nvgQuadTo(getContext(), cx, cy, x, y);
}
void NVG::arcTo(float x1, float y1, float x2, float y2, float radius) {
nvgArcTo(getContext(), x1, y1, x2, y2, radius);
}
void NVG::closePath() {
nvgClosePath(getContext());
}
void NVG::pathWinding(int dir) {
nvgPathWinding(getContext(), dir);
}
void NVG::arc(float cx, float cy, float r, float a0, float a1, int dir) {
nvgArc(getContext(), cx, cy, r, a0, a1, dir);
}
void NVG::rect(float x, float y, float w, float h) {
nvgRect(getContext(), x, y, w, h);
}
void NVG::roundedRect(float x, float y, float w, float h, float r) {
nvgRoundedRect(getContext(), x, y, w, h, r);
}
void NVG::roundedRectVarying(float x, float y, float w, float h, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft) {
nvgRoundedRectVarying(getContext(), x, y, w, h, radTopLeft, radTopRight, radBottomRight, radBottomLeft);
}
void NVG::ellipse(float cx, float cy, float rx, float ry) {
nvgEllipse(getContext(), cx, cy, rx, ry);
}
void NVG::circle(float cx, float cy, float r) {
nvgCircle(getContext(), cx, cy, r);
}
void NVG::fill() {
nvgFill(getContext());
}
void NVG::stroke() {
nvgStroke(getContext());
}
} //namespace detail
int createFont(const char* name, const char* filename) {
return detail::get_current_context()->createFont(name,filename);
}
int createFontMem(const char* name, unsigned char* data, int ndata, int freeData) {
return detail::get_current_context()->createFontMem(name, data, ndata, freeData);
}
int findFont(const char* name) {
return detail::get_current_context()->findFont(name);
}
int addFallbackFontId(int baseFont, int fallbackFont) {
return detail::get_current_context()->addFallbackFontId(baseFont, fallbackFont);
}
int addFallbackFont(const char* baseFont, const char* fallbackFont) {
return detail::get_current_context()->addFallbackFont(baseFont, fallbackFont);
}
void fontSize(float size) {
detail::get_current_context()->fontSize(size);
}
void fontBlur(float blur) {
detail::get_current_context()->fontBlur(blur);
}
void textLetterSpacing(float spacing) {
detail::get_current_context()->textLetterSpacing(spacing);
}
void textLineHeight(float lineHeight) {
detail::get_current_context()->textLineHeight(lineHeight);
}
void textAlign(int align) {
detail::get_current_context()->textAlign(align);
}
void fontFaceId(int font) {
detail::get_current_context()->fontFaceId(font);
}
void fontFace(const char* font) {
detail::get_current_context()->fontFace(font);
}
float text(float x, float y, const char* string, const char* end) {
return detail::get_current_context()->text(x, y, string, end);
}
void textBox(float x, float y, float breakRowWidth, const char* string, const char* end) {
detail::get_current_context()->textBox(x, y, breakRowWidth, string, end);
}
float textBounds(float x, float y, const char* string, const char* end, float* bounds) {
return detail::get_current_context()->textBounds(x, y, string, end, bounds);
}
void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds) {
detail::get_current_context()->textBoxBounds(x, y, breakRowWidth, string, end, bounds);
}
int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition* positions, int maxPositions) {
return detail::get_current_context()->textGlyphPositions(x, y, string, end, positions, maxPositions);
}
void textMetrics(float* ascender, float* descender, float* lineh) {
detail::get_current_context()->textMetrics(ascender, descender, lineh);
}
int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow* rows, int maxRows) {
return detail::get_current_context()->textBreakLines(string, end, breakRowWidth, rows, maxRows);
}
void save() {
detail::get_current_context()->save();
}
void restore() {
detail::get_current_context()->restore();
}
void reset() {
detail::get_current_context()->reset();
}
void shapeAntiAlias(int enabled) {
detail::get_current_context()->strokeColor(enabled);
}
void strokeColor(const cv::Scalar& bgra) {
detail::get_current_context()->strokeColor(bgra);
}
void strokePaint(Paint paint) {
detail::get_current_context()->strokePaint(paint);
}
void fillColor(const cv::Scalar& color) {
detail::get_current_context()->fillColor(color);
}
void fillPaint(Paint paint) {
detail::get_current_context()->fillPaint(paint);
}
void miterLimit(float limit) {
detail::get_current_context()->miterLimit(limit);
}
void strokeWidth(float size) {
detail::get_current_context()->strokeWidth(size);
}
void lineCap(int cap) {
detail::get_current_context()->lineCap(cap);
}
void lineJoin(int join) {
detail::get_current_context()->lineJoin(join);
}
void globalAlpha(float alpha) {
detail::get_current_context()->globalAlpha(alpha);
}
void resetTransform() {
detail::get_current_context()->resetTransform();
}
void transform(float a, float b, float c, float d, float e, float f) {
detail::get_current_context()->transform(a, b, c, d, e, f);
}
void translate(float x, float y) {
detail::get_current_context()->translate(x, y);
}
void rotate(float angle) {
detail::get_current_context()->rotate(angle);
}
void skewX(float angle) {
detail::get_current_context()->skewX(angle);
}
void skewY(float angle) {
detail::get_current_context()->skewY(angle);
}
void scale(float x, float y) {
detail::get_current_context()->scale(x, y);
}
void currentTransform(float* xform) {
detail::get_current_context()->currentTransform(xform);
}
void transformIdentity(float* dst) {
detail::get_current_context()->transformIdentity(dst);
}
void transformTranslate(float* dst, float tx, float ty) {
detail::get_current_context()->transformTranslate(dst, tx, ty);
}
void transformScale(float* dst, float sx, float sy) {
detail::get_current_context()->transformScale(dst, sx, sy);
}
void transformRotate(float* dst, float a) {
detail::get_current_context()->transformRotate(dst, a);
}
void transformSkewX(float* dst, float a) {
detail::get_current_context()->transformSkewX(dst, a);
}
void transformSkewY(float* dst, float a) {
detail::get_current_context()->transformSkewY(dst, a);
}
void transformMultiply(float* dst, const float* src) {
detail::get_current_context()->transformMultiply(dst, src);
}
void transformPremultiply(float* dst, const float* src) {
detail::get_current_context()->transformPremultiply(dst, src);
}
int transformInverse(float* dst, const float* src) {
return detail::get_current_context()->transformInverse(dst, src);
}
void transformPoint(float* dstx, float* dsty, const float* xform, float srcx, float srcy) {
return detail::get_current_context()->transformPoint(dstx, dsty, xform, srcx, srcy);
}
float degToRad(float deg) {
return detail::get_current_context()->degToRad(deg);
}
float radToDeg(float rad) {
return detail::get_current_context()->radToDeg(rad);
}
void beginPath() {
detail::get_current_context()->beginPath();
}
void moveTo(float x, float y) {
detail::get_current_context()->moveTo(x, y);
}
void lineTo(float x, float y) {
detail::get_current_context()->lineTo(x, y);
}
void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
detail::get_current_context()->bezierTo(c1x, c1y, c2x, c2y, x, y);
}
void quadTo(float cx, float cy, float x, float y) {
detail::get_current_context()->quadTo(cx, cy, x, y);
}
void arcTo(float x1, float y1, float x2, float y2, float radius) {
detail::get_current_context()->arcTo(x1, y1, x2, y2, radius);
}
void closePath() {
detail::get_current_context()->closePath();
}
void pathWinding(int dir) {
detail::get_current_context()->pathWinding(dir);
}
void arc(float cx, float cy, float r, float a0, float a1, int dir) {
detail::get_current_context()->arc(cx, cy, r, a0, a1, dir);
}
void rect(float x, float y, float w, float h) {
detail::get_current_context()->rect(x, y, w, h);
}
void roundedRect(float x, float y, float w, float h, float r) {
detail::get_current_context()->roundedRect(x, y, w, h, r);
}
void roundedRectVarying(float x, float y, float w, float h, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft) {
detail::get_current_context()->roundedRectVarying(x, y, w, h, radTopLeft, radTopRight, radBottomRight, radBottomLeft);
}
void ellipse(float cx, float cy, float rx, float ry) {
detail::get_current_context()->ellipse(cx, cy, rx, ry);
}
void circle(float cx, float cy, float r) {
detail::get_current_context()->circle(cx, cy, r);
}
void fill() {
detail::get_current_context()->fill();
}
void stroke() {
detail::get_current_context()->stroke();
}
} //namespace nvg
} //namespace kb

@ -0,0 +1,208 @@
#ifndef SRC_COMMON_NVG_HPP_
#define SRC_COMMON_NVG_HPP_
#include "viz2d.hpp"
#define NANOGUI_USE_OPENGL
#include <nanogui/opengl.h>
namespace kb {
namespace nvg {
struct TextRow {
const char* start; // Pointer to the input text where the row starts.
const char* end; // Pointer to the input text where the row ends (one past the last character).
const char* next; // Pointer to the beginning of the next row.
float width; // Logical width of the row.
float minx, maxx; // Actual bounds of the row. Logical with and bounds can differ because of kerning and some parts over extending.
};
struct GlyphPosition {
const char* str; // Position of the glyph in the input string.
float x; // The x-coordinate of the logical glyph position.
float minx, maxx; // The bounds of the glyph shape.
};
struct Paint {
float xform[6];
float extent[2];
float radius;
float feather;
cv::Scalar innerColor;
cv::Scalar outerColor;
int image;
};
namespace detail {
class NVG {
friend class Viz2D;
NVGcontext* ctx_;
public:
NVG(NVGcontext* ctx) : ctx_(ctx) {
}
NVGcontext* getContext() {
return ctx_;
}
public:
int createFont(const char* name, const char* filename);
int createFontMem(const char* name, unsigned char* data, int ndata, int freeData);
int findFont(const char* name);
int addFallbackFontId(int baseFont, int fallbackFont);
int addFallbackFont(const char* baseFont, const char* fallbackFont);
void fontSize(float size);
void fontBlur(float blur);
void textLetterSpacing(float spacing);
void textLineHeight(float lineHeight);
void textAlign(int align);
void fontFaceId(int font);
void fontFace(const char* font);
float text(float x, float y, const char* string, const char* end);
void textBox(float x, float y, float breakRowWidth, const char* string, const char* end);
float textBounds(float x, float y, const char* string, const char* end, float* bounds);
void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds);
int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition* positions, int maxPositions);
void textMetrics(float* ascender, float* descender, float* lineh);
int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow* rows, int maxRows);
void save();
void restore();
void reset();
void shapeAntiAlias(int enabled);
void strokeColor(const cv::Scalar& bgra);
void strokePaint(Paint paint);
void fillColor(const cv::Scalar& bgra);
void fillPaint(Paint paint);
void miterLimit(float limit);
void strokeWidth(float size);
void lineCap(int cap);
void lineJoin(int join);
void globalAlpha(float alpha);
void resetTransform();
void transform(float a, float b, float c, float d, float e, float f);
void translate(float x, float y);
void rotate(float angle);
void skewX(float angle);
void skewY(float angle);
void scale(float x, float y);
void currentTransform(float* xform);
void transformIdentity(float* dst);
void transformTranslate(float* dst, float tx, float ty);
void transformScale(float* dst, float sx, float sy);
void transformRotate(float* dst, float a);
void transformSkewX(float* dst, float a);
void transformSkewY(float* dst, float a);
void transformMultiply(float* dst, const float* src);
void transformPremultiply(float* dst, const float* src);
int transformInverse(float* dst, const float* src);
void transformPoint(float* dstx, float* dsty, const float* xform, float srcx, float srcy);
float degToRad(float deg);
float radToDeg(float rad);
void beginPath();
void moveTo(float x, float y);
void lineTo(float x, float y);
void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y);
void quadTo(float cx, float cy, float x, float y);
void arcTo(float x1, float y1, float x2, float y2, float radius);
void closePath();
void pathWinding(int dir);
void arc(float cx, float cy, float r, float a0, float a1, int dir);
void rect(float x, float y, float w, float h);
void roundedRect(float x, float y, float w, float h, float r);
void roundedRectVarying(float x, float y, float w, float h, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft);
void ellipse(float cx, float cy, float rx, float ry);
void circle(float cx, float cy, float r);
void fill();
void stroke();
};
static NVG* nvg_instance;
void set_current_context(NVGcontext* ctx);
NVG* get_current_context();
} // namespace detail
int createFont(const char* name, const char* filename);
int createFontMem(const char* name, unsigned char* data, int ndata, int freeData);
int findFont(const char* name);
int addFallbackFontId(int baseFont, int fallbackFont);
int addFallbackFont(const char* baseFont, const char* fallbackFont);
void fontSize(float size);
void fontBlur(float blur);
void textLetterSpacing(float spacing);
void textLineHeight(float lineHeight);
void textAlign(int align);
void fontFaceId(int font);
void fontFace(const char* font);
float text(float x, float y, const char* string, const char* end);
void textBox(float x, float y, float breakRowWidth, const char* string, const char* end);
float textBounds(float x, float y, const char* string, const char* end, float* bounds);
void textBoxBounds(float x, float y, float breakRowWidth, const char* string, const char* end, float* bounds);
int textGlyphPositions(float x, float y, const char* string, const char* end, GlyphPosition* positions, int maxPositions);
void textMetrics(float* ascender, float* descender, float* lineh);
int textBreakLines(const char* string, const char* end, float breakRowWidth, TextRow* rows, int maxRows);
void save();
void restore();
void reset();
void shapeAntiAlias(int enabled);
void strokeColor(const cv::Scalar& bgra);
void strokePaint(Paint paint);
void fillColor(const cv::Scalar& color);
void fillPaint(Paint paint);
void miterLimit(float limit);
void strokeWidth(float size);
void lineCap(int cap);
void lineJoin(int join);
void globalAlpha(float alpha);
void resetTransform();
void transform(float a, float b, float c, float d, float e, float f);
void translate(float x, float y);
void rotate(float angle);
void skewX(float angle);
void skewY(float angle);
void scale(float x, float y);
void currentTransform(float* xform);
void transformIdentity(float* dst);
void transformTranslate(float* dst, float tx, float ty);
void transformScale(float* dst, float sx, float sy);
void transformRotate(float* dst, float a);
void transformSkewX(float* dst, float a);
void transformSkewY(float* dst, float a);
void transformMultiply(float* dst, const float* src);
void transformPremultiply(float* dst, const float* src);
int transformInverse(float* dst, const float* src);
void transformPoint(float* dstx, float* dsty, const float* xform, float srcx, float srcy);
float degToRad(float deg);
float radToDeg(float rad);
void beginPath();
void moveTo(float x, float y);
void lineTo(float x, float y);
void bezierTo(float c1x, float c1y, float c2x, float c2y, float x, float y);
void quadTo(float cx, float cy, float x, float y);
void arcTo(float x1, float y1, float x2, float y2, float radius);
void closePath();
void pathWinding(int dir);
void arc(float cx, float cy, float r, float a0, float a1, int dir);
void rect(float x, float y, float w, float h);
void roundedRect(float x, float y, float w, float h, float r);
void roundedRectVarying(float x, float y, float w, float h, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft);
void ellipse(float cx, float cy, float rx, float ry);
void circle(float cx, float cy, float r);
void fill();
void stroke();
} // namespace nvg
} // namespace kb
#endif /* SRC_COMMON_NVG_HPP_ */

@ -1,8 +1,19 @@
#include "util.hpp"
#include "viz2d.hpp"
#include "nvg.hpp"
namespace kb {
namespace viz2d {
void gl_check_error(const std::filesystem::path &file, unsigned int line, const char *expression) {
int errorCode = glGetError();
if (errorCode != 0) {
std::cerr << "GL failed in " << file.filename() << " (" << line << ") : " << "\nExpression:\n " << expression << "\nError code:\n " << errorCode << "\n " << std::endl;
assert(false);
}
}
void error_callback(int error, const char *description) {
fprintf(stderr, "GLFW Error: %s\n", description);
@ -41,7 +52,7 @@ void print_system_info() {
cerr << "OpenCL Platforms: " << get_cl_info() << endl;
}
void update_fps(cv::Ptr<kb::Viz2D> window, bool graphical) {
void update_fps(cv::Ptr<kb::viz2d::Viz2D> window, bool graphical) {
static uint64_t cnt = 0;
static cv::TickMeter tick;
float fps;
@ -52,19 +63,20 @@ void update_fps(cv::Ptr<kb::Viz2D> window, bool graphical) {
if (tick.getTimeMilli() > 1000) {
cerr << "FPS : " << (fps = tick.getFPS()) << '\r';
if (graphical) {
window->nanovg([&](NVGcontext *vg, const cv::Size &size) {
window->nanovg([&](const cv::Size &size) {
using namespace kb;
string text = "FPS: " + std::to_string(fps);
nvgBeginPath(vg);
nvgRoundedRect(vg, 10, 10, 30 * text.size() + 10, 60, 10);
nvgFillColor(vg, nvgRGBA(255, 255, 255, 180));
nvgFill(vg);
nvg::beginPath();
nvg::roundedRect(10, 10, 30 * text.size() + 10, 60, 10);
nvg::fillColor(cv::Scalar(255, 255, 255, 180));
nvg::fill();
nvgBeginPath(vg);
nvgFontSize(vg, 60.0f);
nvgFontFace(vg, "mono");
nvgFillColor(vg, nvgRGBA(90, 90, 90, 255));
nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
nvgText(vg, 22, 37, text.c_str(), nullptr);
nvg::beginPath();
nvg::fontSize(60.0f);
nvg::fontFace("mono");
nvg::fillColor(cv::Scalar(90, 90, 90, 255));
nvg::textAlign(NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE);
nvg::text(22, 37, text.c_str(), nullptr);
});
}
cnt = 0;
@ -74,5 +86,5 @@ void update_fps(cv::Ptr<kb::Viz2D> window, bool graphical) {
tick.start();
++cnt;
}
}
} //namespace kb

@ -8,17 +8,20 @@
#include <opencv2/core/ocl.hpp>
namespace kb {
namespace viz2d {
class Viz2D;
void gl_check_error(const std::filesystem::path &file, unsigned int line, const char *expression);
typedef cv::ocl::OpenCLExecutionContext CLExecContext_t;
typedef cv::ocl::OpenCLExecutionContextScope CLExecScope_t;
#define GL_CHECK(expr) \
expr; \
kb::viz2d::gl_check_error(__FILE__, __LINE__, #expr);
void error_callback(int error, const char *description);
std::string get_gl_info();
std::string get_cl_info();
void print_system_info();
void update_fps(cv::Ptr<Viz2D> viz2d, bool graphical);
} //namespace kb
//void update_fps(cv::Ptr<Viz2D> viz2d, bool graphical);
}
}
#endif /* SRC_COMMON_UTIL_HPP_ */

@ -1,16 +1,10 @@
#include "viz2d.hpp"
#include "util.hpp"
#include "detail/clglcontext.hpp"
#include "detail/clvacontext.hpp"
#include "detail/nanovgcontext.hpp"
namespace kb {
void gl_check_error(const std::filesystem::path &file, unsigned int line, const char *expression) {
int errorCode = glGetError();
if (errorCode != 0) {
std::cerr << "GL failed in " << file.filename() << " (" << line << ") : " << "\nExpression:\n " << expression << "\nError code:\n " << errorCode << "\n " << std::endl;
assert(false);
}
}
namespace viz2d {
Viz2D::Viz2D(const cv::Size &size, const cv::Size& frameBufferSize, bool offscreen, const string &title, int major, int minor, int samples, bool debug) :
size_(size), frameBufferSize_(frameBufferSize), offscreen_(offscreen), title_(title), major_(major), minor_(minor), samples_(samples), debug_(debug) {
@ -18,9 +12,7 @@ Viz2D::Viz2D(const cv::Size &size, const cv::Size& frameBufferSize, bool offscre
}
Viz2D::~Viz2D() {
//don't delete form_. it is autmatically cleaned up by screen_
if (screen_)
delete screen_;
//don't delete form_. it is autmatically cleaned up by the base class (nanogui::Screen)
if (writer_)
delete writer_;
if (capture_)
@ -37,7 +29,7 @@ Viz2D::~Viz2D() {
void Viz2D::initialize() {
assert(glfwInit() == GLFW_TRUE);
glfwSetErrorCallback(kb::error_callback);
glfwSetErrorCallback(kb::viz2d::error_callback);
if (debug_)
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
@ -81,45 +73,43 @@ void Viz2D::initialize() {
}
glfwMakeContextCurrent(getGLFWWindow());
screen_ = new nanogui::Screen();
screen_->initialize(getGLFWWindow(), false);
form_ = new nanogui::FormHelper(screen_);
screen().initialize(getGLFWWindow(), false);
form_ = new nanogui::FormHelper(this);
this->setSize(size_);
glfwSetWindowUserPointer(getGLFWWindow(), this);
glfwSetCursorPosCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, double x, double y) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->cursor_pos_callback_event(x, y);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().cursor_pos_callback_event(x, y);
}
);
glfwSetMouseButtonCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, int button, int action, int modifiers) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->mouse_button_callback_event(button, action, modifiers);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().mouse_button_callback_event(button, action, modifiers);
}
);
glfwSetKeyCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, int key, int scancode, int action, int mods) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->key_callback_event(key, scancode, action, mods);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().key_callback_event(key, scancode, action, mods);
}
);
glfwSetCharCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, unsigned int codepoint) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->char_callback_event(codepoint);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().char_callback_event(codepoint);
}
);
glfwSetDropCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, int count, const char **filenames) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->drop_callback_event(count, filenames);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().drop_callback_event(count, filenames);
}
);
glfwSetScrollCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, double x, double y) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->scroll_callback_event(x, y);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().scroll_callback_event(x, y);
}
);
//FIXME resize internal buffers?
// glfwSetWindowContentScaleCallback(getGLFWWindow(),
// [](GLFWwindow* glfwWin, float xscale, float yscale) {
@ -127,14 +117,14 @@ void Viz2D::initialize() {
// );
glfwSetFramebufferSizeCallback(getGLFWWindow(), [](GLFWwindow *glfwWin, int width, int height) {
Viz2D *v2d = (Viz2D*) glfwGetWindowUserPointer(glfwWin);
v2d->screen_->resize_callback_event(width, height);
Viz2D* v2d = reinterpret_cast<Viz2D*>(glfwGetWindowUserPointer(glfwWin));
v2d->screen().resize_callback_event(width, height);
}
);
clglContext_ = new CLGLContext(this->getFrameBufferSize());
clvaContext_ = new CLVAContext(*clglContext_);
nvgContext_ = new NanoVGContext(*this, getNVGcontext(), *clglContext_);
clglContext_ = new detail::CLGLContext(this->getFrameBufferSize());
clvaContext_ = new detail::CLVAContext(*clglContext_);
nvgContext_ = new detail::NanoVGContext(*this, getNVGcontext(), *clglContext_);
}
cv::ogl::Texture2D& Viz2D::texture() {
@ -145,6 +135,23 @@ nanogui::FormHelper* Viz2D::form() {
return form_;
}
bool Viz2D::keyboard_event(int key, int scancode, int action, int modifiers) {
if (nanogui::Screen::keyboard_event(key, scancode, action, modifiers))
return true;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
nanogui::Screen::set_visible(!screen().visible());
return true;
} else if (key == GLFW_KEY_TAB && action == GLFW_PRESS) {
auto children = nanogui::Screen::children();
for(auto* child : children) {
child->set_visible(!child->visible());
}
return true;
}
return false;
}
CLGLContext& Viz2D::clgl() {
return *clglContext_;
}
@ -157,6 +164,10 @@ NanoVGContext& Viz2D::nvg() {
return *nvgContext_;
}
nanogui::Screen& Viz2D::screen() {
return *dynamic_cast<nanogui::Screen*>(this);
}
cv::Size Viz2D::getVideoFrameSize() {
return clva().getVideoFrameSize();
}
@ -166,8 +177,8 @@ void Viz2D::setVideoFrameSize(const cv::Size& sz) {
}
void Viz2D::opengl(std::function<void(const cv::Size&)> fn) {
CLExecScope_t scope(clglContext_->getCLExecContext());
CLGLContext::GLScope glScope(*clglContext_);
detail::CLExecScope_t scope(clglContext_->getCLExecContext());
detail::CLGLContext::GLScope glScope(*clglContext_);
fn(getFrameBufferSize());
}
@ -175,7 +186,7 @@ void Viz2D::opencl(std::function<void(cv::UMat&)> fn) {
clgl().opencl(fn);
}
void Viz2D::nanovg(std::function<void(NVGcontext*, const cv::Size&)> fn) {
void Viz2D::nanovg(std::function<void(const cv::Size&)> fn) {
nvg().render(fn);
}
@ -265,7 +276,7 @@ float Viz2D::getYPixelRatio() {
}
void Viz2D::setSize(const cv::Size &sz) {
screen_->set_size(nanogui::Vector2i(sz.width / getXPixelRatio(), sz.height / getYPixelRatio()));
screen().set_size(nanogui::Vector2i(sz.width / getXPixelRatio(), sz.height / getYPixelRatio()));
}
bool Viz2D::isFullscreen() {
@ -296,9 +307,9 @@ bool Viz2D::isVisible() {
}
void Viz2D::setVisible(bool v) {
screen_->perform_layout();
screen().perform_layout();
glfwWindowHint(GLFW_VISIBLE, v ? GLFW_TRUE : GLFW_FALSE);
screen_->set_visible(v);
screen().set_visible(v);
setSize(size_);
}
@ -331,9 +342,9 @@ bool Viz2D::display() {
bool result = true;
if (!offscreen_) {
glfwPollEvents();
screen_->draw_contents();
screen().draw_contents();
clglContext_->blitFrameBufferToScreen(getSize());
screen_->draw_widgets();
screen().draw_widgets();
glfwSwapBuffers(glfwWindow_);
result = !glfwWindowShouldClose(glfwWindow_);
}
@ -355,6 +366,7 @@ GLFWwindow* Viz2D::getGLFWWindow() {
}
NVGcontext* Viz2D::getNVGcontext() {
return screen_->nvg_context();
return screen().nvg_context();
}
}
}
} /* namespace kb */

@ -4,10 +4,8 @@
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include "clglcontext.hpp"
#include "clvacontext.hpp"
#include "nanovgcontext.hpp"
#include <nanogui/nanogui.h>
#include <GL/glew.h>
using std::cout;
using std::cerr;
@ -15,13 +13,17 @@ using std::endl;
using std::string;
namespace kb {
namespace viz2d {
namespace detail {
class CLGLContext;
class CLVAContext;
class NanoVGContext;
}
using namespace kb::viz2d::detail;
void gl_check_error(const std::filesystem::path &file, unsigned int line, const char *expression);
#define GL_CHECK(expr) \
expr; \
kb::gl_check_error(__FILE__, __LINE__, #expr);
class NVG;
class Viz2D {
class Viz2D: private nanogui::Screen {
cv::Size size_;
cv::Size frameBufferSize_;
bool offscreen_;
@ -36,19 +38,18 @@ class Viz2D {
NanoVGContext* nvgContext_ = nullptr;
cv::VideoCapture* capture_ = nullptr;
cv::VideoWriter* writer_ = nullptr;
nanogui::Screen* screen_ = nullptr;
nanogui::FormHelper* form_ = nullptr;
bool closed_ = false;
cv::Size videoFrameSize_ = cv::Size(0,0);
public:
Viz2D(const cv::Size &size, const cv::Size& frameBufferSize, bool offscreen, const string &title, int major = 4, int minor = 6, int samples = 0, bool debug = false);
~Viz2D();
virtual ~Viz2D();
void initialize();
cv::ogl::Texture2D& texture();
void opengl(std::function<void(const cv::Size&)> fn);
void opencl(std::function<void(cv::UMat&)> fn);
void nanovg(std::function<void(NVGcontext*, const cv::Size&)> fn);
void nanovg(std::function<void(const cv::Size&)> fn);
void clear(const cv::Scalar& rgba = cv::Scalar(0,0,0,255));
bool captureVA();
@ -92,15 +93,18 @@ public:
}
void setUseOpenCL(bool u);
NVGcontext* getNVGcontext();
private:
virtual bool keyboard_event(int key, int scancode, int action, int modifiers);
CLGLContext& clgl();
CLVAContext& clva();
NanoVGContext& nvg();
nanogui::Screen& screen();
void makeGLFWContextCurrent();
GLFWwindow* getGLFWWindow();
NVGcontext* getNVGcontext();
};
}
} /* namespace kb */
#endif /* SRC_COMMON_VIZ2D_HPP_ */

@ -2,6 +2,10 @@
#define CL_TARGET_OPENCL_VERSION 120
#include "../common/viz2d.hpp"
#include "../common/nvg.hpp"
#include "../common/util.hpp"
#include <cmath>
#include <vector>
#include <string>
@ -10,6 +14,7 @@
#include <opencv2/features2d.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/optflow.hpp>
#include <opencv2/core/ocl.hpp>
using std::cerr;
using std::endl;
@ -92,7 +97,7 @@ bool detect_scene_change(const cv::UMat& srcMotionMaskGrey, const float thresh,
return result;
}
void visualize_sparse_optical_flow(NVGcontext* vg, const cv::UMat &prevGrey, const cv::UMat &nextGrey, vector<cv::Point2f> &detectedPoints,
void visualize_sparse_optical_flow(const cv::UMat &prevGrey, const cv::UMat &nextGrey, vector<cv::Point2f> &detectedPoints,
const float scaleFactor, const int maxStrokeSize, const cv::Scalar color, const int maxPoints, const float pointLossPercent) {
static vector<cv::Point2f> hull, prevPoints, nextPoints, newPoints;
static vector<cv::Point2f> upPrevPoints, upNextPoints;
@ -127,9 +132,10 @@ void visualize_sparse_optical_flow(NVGcontext* vg, const cv::UMat &prevGrey, con
upNextPoints.push_back(pt /= scaleFactor);
}
nvgBeginPath(vg);
nvgStrokeWidth(vg, stroke);
nvgStrokeColor(vg, nvgRGBA(color[0], color[1], color[2], color[3]));
using namespace kb;
nvg::beginPath();
nvg::strokeWidth(stroke);
nvg::strokeColor(color);
for (size_t i = 0; i < prevPoints.size(); i++) {
if (status[i] == 1 && err[i] < (1.0 / density)
@ -139,12 +145,12 @@ void visualize_sparse_optical_flow(NVGcontext* vg, const cv::UMat &prevGrey, con
float len = hypot(fabs(upPrevPoints[i].x - upNextPoints[i].x), fabs(upPrevPoints[i].y - upNextPoints[i].y));
if (len > 0 && len < sqrt(area)) {
newPoints.push_back(nextPoints[i]);
nvgMoveTo(vg, upNextPoints[i].x, upNextPoints[i].y);
nvgLineTo(vg, upPrevPoints[i].x, upPrevPoints[i].y);
nvg::moveTo(upNextPoints[i].x, upNextPoints[i].y);
nvg::lineTo(upPrevPoints[i].x, upPrevPoints[i].y);
}
}
}
nvgStroke(vg);
nvg::stroke();
}
prevPoints = newPoints;
}
@ -184,60 +190,61 @@ void composite_layers(const cv::UMat background, const cv::UMat foreground, cons
cv::add(background, glow, dst);
}
void setup_gui(cv::Ptr<kb::Viz2D> window) {
window->makeWindow(5, 45, "Settings");
void setup_gui(cv::Ptr<kb::viz2d::Viz2D> v2d) {
v2d->makeWindow(5, 45, "Settings");
v2d->makeFormVariable("Use OpenCL", use_opencl, "Enable or disable OpenCL acceleration");
v2d->makeGroup("Foreground");
v2d->makeFormVariable("Scale", fg_scale, 0.1f, 4.0f, true, "", "Generate the foreground at this scale");
v2d->makeFormVariable("Loss", fg_loss, 0.1f, 99.9f, true, "%", "On every frame the foreground loses on brightness");
window->makeFormVariable("Use OpenCL", use_opencl, "Enable or disable OpenCL acceleration");
window->makeGroup("Foreground");
window->makeFormVariable("Scale", fg_scale, 0.1f, 4.0f, true, "", "Generate the foreground at this scale");
window->makeFormVariable("Loss", fg_loss, 0.1f, 99.9f, true, "%", "On every frame the foreground loses on brightness");
v2d->makeGroup("Scene Change Detection");
v2d->makeFormVariable("Threshold", scene_change_thresh, 0.1f, 1.0f, true, "", "Peak threshold. Lowering it makes detection more sensitive");
v2d->makeFormVariable("Threshold Diff", scene_change_thresh_diff, 0.1f, 1.0f, true, "", "Difference of peak thresholds. Lowering it makes detection more sensitive");
window->makeGroup("Scene Change Detection");
window->makeFormVariable("Threshold", scene_change_thresh, 0.1f, 1.0f, true, "", "Peak threshold. Lowering it makes detection more sensitive");
window->makeFormVariable("Threshold Diff", scene_change_thresh_diff, 0.1f, 1.0f, true, "", "Difference of peak thresholds. Lowering it makes detection more sensitive");
v2d->makeGroup("Points");
v2d->makeFormVariable("Max. Points", max_points, 10, 1000000, true, "", "The theoretical maximum number of points to track which is scaled by the density of detected points and therefor is usually much smaller");
v2d->makeFormVariable("Point Loss", point_loss, 0.0f, 100.0f, true, "%", "How many of the tracked points to lose intentionally");
window->makeGroup("Points");
window->makeFormVariable("Max. Points", max_points, 10, 1000000, true, "", "The theoretical maximum number of points to track which is scaled by the density of detected points and therefor is usually much smaller");
window->makeFormVariable("Point Loss", point_loss, 0.0f, 100.0f, true, "%", "How many of the tracked points to lose intentionally");
window->makeGroup("Effect");
window->makeFormVariable("Max. Stroke Size", max_stroke, 1, 100, true, "px", "The theoretical maximum size of the drawing stroke which is scaled by the area of the convex hull of tracked points and therefor is usually much smaller");
auto glowKernel = window->makeFormVariable("Glow Kernel Size", glow_kernel_size, 1, 63, true, "", "Intensity of glow defined by kernel size");
v2d->makeGroup("Effect");
v2d->makeFormVariable("Max. Stroke Size", max_stroke, 1, 100, true, "px", "The theoretical maximum size of the drawing stroke which is scaled by the area of the convex hull of tracked points and therefor is usually much smaller");
auto glowKernel = v2d->makeFormVariable("Glow Kernel Size", glow_kernel_size, 1, 63, true, "", "Intensity of glow defined by kernel size");
glowKernel->set_callback([](const int& k) {
glow_kernel_size = std::max(int(k % 2 == 0 ? k + 1 : k), 1);
});
auto color = window->form()->add_variable("Color", effect_color);
auto color = v2d->form()->add_variable("Color", effect_color);
color->set_tooltip("The effect color");
color->set_final_callback([](const nanogui::Color &c) {
effect_color[0] = c[0];
effect_color[1] = c[1];
effect_color[2] = c[2];
});
window->makeFormVariable("Alpha", alpha, 0.0f, 1.0f, true, "", "The opacity of the effect");
v2d->makeFormVariable("Alpha", alpha, 0.0f, 1.0f, true, "", "The opacity of the effect");
window->makeWindow(240, 45, "Display");
window->makeGroup("Display");
window->makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display");
window->form()->add_button("Fullscreen", [=]() {
window->setFullscreen(!window->isFullscreen());
v2d->makeWindow(240, 45, "Display");
v2d->makeGroup("Display");
v2d->makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display");
v2d->form()->add_button("Fullscreen", [=]() {
v2d->setFullscreen(!v2d->isFullscreen());
});
if(!window->isOffscreen())
window->setVisible(true);
if(!v2d->isOffscreen())
v2d->setVisible(true);
}
int main(int argc, char **argv) {
using namespace kb::viz2d;
if (argc != 2) {
std::cerr << "Usage: optflow <input-video-file>" << endl;
exit(1);
}
cv::Ptr<kb::Viz2D> v2d = new kb::Viz2D(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Sparse Optical Flow Demo");
cv::Ptr<Viz2D> v2d = new Viz2D(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Sparse Optical Flow Demo");
v2d->initialize();
kb::print_system_info();
print_system_info();
setup_gui(v2d);
auto capture = v2d->makeVACapture(argv[1], VA_HW_DEVICE_INDEX);
@ -278,14 +285,14 @@ int main(int argc, char **argv) {
//Detect trackable points in the motion mask
detect_points(downMotionMaskGrey, detectedPoints);
v2d->nanovg([&](NVGcontext* vg, const cv::Size& sz) {
v2d->nanovg([&](const cv::Size& sz) {
v2d->clear();
if (!downPrevGrey.empty()) {
//We don't want the algorithm to get out of hand when there is a scene change, so we suppress it when we detect one.
if (!detect_scene_change(downMotionMaskGrey, scene_change_thresh, scene_change_thresh_diff)) {
//Visualize the sparse optical flow using nanovg
cv::Scalar color = cv::Scalar(effect_color.r() * 255.0f, effect_color.g() * 255.0f, effect_color.b() * 255.0f, alpha * 255.0f);
visualize_sparse_optical_flow(vg, downPrevGrey, downNextGrey, detectedPoints, fg_scale, max_stroke, color, max_points, point_loss);
cv::Scalar color = cv::Scalar(effect_color.b() * 255.0f, effect_color.g() * 255.0f, effect_color.r() * 255.0f, alpha * 255.0f);
visualize_sparse_optical_flow(downPrevGrey, downNextGrey, detectedPoints, fg_scale, max_stroke, color, max_points, point_loss);
}
}
});
@ -299,7 +306,7 @@ int main(int argc, char **argv) {
v2d->writeVA();
update_fps(v2d, show_fps);
// update_fps(v2d, show_fps);
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
if(!v2d->display())

@ -1,6 +1,8 @@
#define CL_TARGET_OPENCL_VERSION 120
#include "../common/viz2d.hpp"
#include "../common/util.hpp"
#include <string>
constexpr long unsigned int WIDTH = 1920;
@ -80,20 +82,20 @@ void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
}
int main(int argc, char **argv) {
using namespace kb;
using namespace kb::viz2d;
if(argc != 2) {
cerr << "Usage: video-demo <video-file>" << endl;
exit(1);
}
cv::Ptr<kb::Viz2D> v2d = new kb::Viz2D(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Video Demo");
cv::Ptr<Viz2D> v2d = new Viz2D(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Video Demo");
v2d->initialize();
if(!v2d->isOffscreen())
v2d->setVisible(true);
//Print system information
kb::print_system_info();
print_system_info();
auto capture = v2d->makeVACapture(argv[1], VA_HW_DEVICE_INDEX);

Loading…
Cancel
Save