brushing up demos & examples

pull/3471/head
kallaballa 2 years ago
parent 2522685b13
commit 20e6a4cb7a
  1. 67
      modules/v4d/samples/beauty-demo.cpp
  2. 31
      modules/v4d/samples/cube-demo.cpp
  3. 32
      modules/v4d/samples/font-demo.cpp
  4. 30
      modules/v4d/samples/nanovg-demo.cpp
  5. 70
      modules/v4d/samples/optflow-demo.cpp
  6. 40
      modules/v4d/samples/pedestrian-demo.cpp
  7. 2
      modules/v4d/samples/render_opengl.cpp
  8. 33
      modules/v4d/samples/shader-demo.cpp
  9. 5
      modules/v4d/samples/vector_graphics.cpp
  10. 7
      modules/v4d/samples/vector_graphics_and_fb.cpp
  11. 30
      modules/v4d/samples/video-demo.cpp
  12. 7
      modules/v4d/src/detail/glcontext.cpp
  13. 10
      modules/v4d/src/detail/nanoguicontext.cpp
  14. 7
      modules/v4d/src/detail/nanovgcontext.cpp

@ -4,16 +4,15 @@
// Copyright Amir Hassan (kallaballa) <amir@viel-zu.org> // Copyright Amir Hassan (kallaballa) <amir@viel-zu.org>
#include <opencv2/v4d/v4d.hpp> #include <opencv2/v4d/v4d.hpp>
#include <vector>
#include <string>
#include <opencv2/dnn.hpp> #include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
#include <opencv2/face.hpp> #include <opencv2/face.hpp>
#include <opencv2/stitching/detail/blenders.hpp> #include <opencv2/stitching/detail/blenders.hpp>
#include <opencv2/tracking.hpp> #include <opencv2/tracking.hpp>
#include <vector>
#include <string>
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::vector; using std::vector;
@ -27,7 +26,8 @@ using std::string;
/** Application parameters **/ /** Application parameters **/
constexpr unsigned int WIDTH = 1280; constexpr unsigned int WIDTH = 1280;
constexpr unsigned int HEIGHT = 720; constexpr unsigned int HEIGHT = 720;
constexpr float SCALE = 0.125; constexpr unsigned int DOWNSIZE_WIDTH = 320;
constexpr unsigned int DOWNSIZE_HEIGHT = 180;
constexpr bool OFFSCREEN = false; constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
constexpr const char *OUTPUT_FILENAME = "beauty-demo.mkv"; constexpr const char *OUTPUT_FILENAME = "beauty-demo.mkv";
@ -48,7 +48,7 @@ bool side_by_side = false;
bool stretch = false; bool stretch = false;
#endif #endif
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
cv::Ptr<cv::face::Facemark> facemark = cv::face::createFacemarkLBF(); //Face landmark detection cv::Ptr<cv::face::Facemark> facemark = cv::face::createFacemarkLBF(); //Face landmark detection
cv::detail::MultiBandBlender blender(false, 5); //Blender (used to put the different face parts back together) cv::detail::MultiBandBlender blender(false, 5); //Blender (used to put the different face parts back together)
@ -204,7 +204,12 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v) {
form.makeGroup("Display"); form.makeGroup("Display");
form.makeFormVariable("Side by side", side_by_side, "Enable or disable side by side view"); form.makeFormVariable("Side by side", side_by_side, "Enable or disable side by side view");
form.makeFormVariable("Stretch", stretch, "Enable or disable stetching to the window size"); auto* stretchVar = form.makeFormVariable("Stretch", stretch, "Enable or disable stetching to the window size");
stretchVar->set_callback([=](const bool& b) {
v->setFrameBufferScaling(b);
stretch = b;
});
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() { form.makeButton("Fullscreen", [=]() {
v->setFullscreen(!v->isFullscreen()); v->setFullscreen(!v->isFullscreen());
@ -245,14 +250,14 @@ static bool iteration() {
#endif #endif
//Face detector //Face detector
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
static cv::Ptr<cv::FaceDetectorYN> detector = cv::FaceDetectorYN::create("assets/face_detection_yunet_2023mar.onnx", "", cv::Size(v4d->framebufferSize().width * SCALE, v4d->framebufferSize().height * SCALE), 0.9, 0.3, 5000, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_TARGET_OPENCL); static cv::Ptr<cv::FaceDetectorYN> detector = cv::FaceDetectorYN::create("assets/face_detection_yunet_2023mar.onnx", "", cv::Size(DOWNSIZE_WIDTH, DOWNSIZE_HEIGHT), 0.9, 0.3, 5000, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_TARGET_OPENCL);
#else #else
static cv::Ptr<cv::FaceDetectorYN> detector = cv::FaceDetectorYN::create("assets/face_detection_yunet_2023mar.onnx", "", cv::Size(v4d->framebufferSize().width * SCALE, v4d->framebufferSize().height * SCALE), 0.9, 0.3, 5000, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_TARGET_CPU); static cv::Ptr<cv::FaceDetectorYN> detector = cv::FaceDetectorYN::create("assets/face_detection_yunet_2023mar.onnx", "", cv::Size(DOWNSIZE_WIDTH, DOWNSIZE_HEIGHT), 0.9, 0.3, 5000, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_TARGET_CPU);
#endif #endif
//BGR //BGR
static cv::UMat input, down, blurred, contrast, faceOval, eyesAndLips, skin; static cv::UMat input, down, blurred, contrast, faceOval, eyesAndLips, skin;
static cv::UMat frameOut(HEIGHT, WIDTH, CV_8UC3); static cv::UMat frameOut(HEIGHT, WIDTH, CV_8UC3);
static cv::UMat lhalf(HEIGHT * SCALE, WIDTH * SCALE, CV_8UC3); static cv::UMat lhalf(DOWNSIZE_HEIGHT, DOWNSIZE_WIDTH, CV_8UC3);
static cv::UMat rhalf(lhalf.size(), lhalf.type()); static cv::UMat rhalf(lhalf.size(), lhalf.type());
//GREY //GREY
static cv::UMat faceSkinMaskGrey, eyesAndLipsMaskGrey, backgroundMaskGrey; static cv::UMat faceSkinMaskGrey, eyesAndLipsMaskGrey, backgroundMaskGrey;
@ -270,15 +275,15 @@ static bool iteration() {
//FaceFeatures of all faces found //FaceFeatures of all faces found
static vector<FaceFeatures> featuresList; static vector<FaceFeatures> featuresList;
if (!v4d->capture()) if (!window->capture())
return false; return false;
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameBuffer, input, cv::COLOR_BGRA2BGR); cvtColor(frameBuffer, input, cv::COLOR_BGRA2BGR);
}); });
//Downscale the input for face detection //Downscale the input for face detection
cv::resize(input, down, cv::Size(0, 0), SCALE, SCALE); cv::resize(input, down, cv::Size(DOWNSIZE_WIDTH, DOWNSIZE_HEIGHT));
shapes.clear(); shapes.clear();
faceRects.clear(); faceRects.clear();
@ -313,22 +318,22 @@ static bool iteration() {
featuresList.push_back(FaceFeatures(faceRects[i], shapes[i], float(down.size().width) / WIDTH)); featuresList.push_back(FaceFeatures(faceRects[i], shapes[i], float(down.size().width) / WIDTH));
} }
v4d->nvg([&]() { window->nvg([&]() {
//Draw the face oval of the first face //Draw the face oval of the first face
draw_face_oval_mask(featuresList); draw_face_oval_mask(featuresList);
}); });
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
//Convert/Copy the mask //Convert/Copy the mask
cvtColor(frameBuffer, faceOval, cv::COLOR_BGRA2GRAY); cvtColor(frameBuffer, faceOval, cv::COLOR_BGRA2GRAY);
}); });
v4d->nvg([&]() { window->nvg([&]() {
//Draw eyes eyes and lips areas of the first face //Draw eyes eyes and lips areas of the first face
draw_face_eyes_and_lips_mask(featuresList); draw_face_eyes_and_lips_mask(featuresList);
}); });
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
//Convert/Copy the mask //Convert/Copy the mask
cvtColor(frameBuffer, eyesAndLipsMaskGrey, cv::COLOR_BGRA2GRAY); cvtColor(frameBuffer, eyesAndLipsMaskGrey, cv::COLOR_BGRA2GRAY);
}); });
@ -367,7 +372,7 @@ static bool iteration() {
rhalf.copyTo(frameOut(cv::Rect(rhalf.size().width, 0, rhalf.size().width, rhalf.size().height))); rhalf.copyTo(frameOut(cv::Rect(rhalf.size().width, 0, rhalf.size().width, rhalf.size().height)));
} }
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA); cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA);
}); });
} else { } else {
@ -380,17 +385,17 @@ static bool iteration() {
input.copyTo(frameOut); input.copyTo(frameOut);
} }
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA); cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA);
}); });
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
v4d->write(); window->write();
#endif #endif
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} catch (std::exception &ex) { } catch (std::exception &ex) {
cerr << ex.what() << endl; cerr << ex.what() << endl;
return false; return false;
@ -401,35 +406,35 @@ static bool iteration() {
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
int main(int argc, char **argv) { int main(int argc, char **argv) {
if (argc != 2) { if (argc != 2) {
std::cerr << "Usage: beauty-demo <input-video-file>" << endl; cerr << "Usage: beauty-demo <input-video-file>" << endl;
exit(1); exit(1);
} }
#else #else
int main() { int main() {
#endif #endif
using namespace cv::v4d; using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Beauty Demo", OFFSCREEN); window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Beauty Demo", OFFSCREEN);
facemark->loadModel("assets/lbfmodel.yaml"); facemark->loadModel("assets/lbfmodel.yaml");
v4d->setFrameBufferScaling(stretch); window->setFrameBufferScaling(stretch);
if (!OFFSCREEN) { if (!OFFSCREEN) {
setup_gui(v4d); setup_gui(window);
} }
v4d->printSystemInfo(); window->printSystemInfo();
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]); Source src = makeCaptureSource(argv[1]);
v4d->setSource(src); window->setSource(src);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), src.fps(), cv::Size(WIDTH, HEIGHT)); Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), src.fps(), cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
#else #else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d); Source src = makeCaptureSource(WIDTH, HEIGHT, window);
v4d->setSource(src); window->setSource(src);
#endif #endif
v4d->run(iteration); window->run(iteration);
return 0; return 0;
} }

@ -4,7 +4,7 @@
// Copyright Amir Hassan (kallaballa) <amir@viel-zu.org> // Copyright Amir Hassan (kallaballa) <amir@viel-zu.org>
#include <opencv2/v4d/v4d.hpp> #include <opencv2/v4d/v4d.hpp>
//adapted from https://g#include "opencv2/v4d/nvg.hpp"itlab.com/wikibooks-opengl/modern-tutorials/-/blob/master/tut05_cube/cube.cpp //adapted from https://gitlab.com/wikibooks-opengl/modern-tutorials/-/blob/master/tut05_cube/cube.cpp
constexpr long unsigned int WIDTH = 1280; constexpr long unsigned int WIDTH = 1280;
constexpr long unsigned int HEIGHT = 720; constexpr long unsigned int HEIGHT = 720;
@ -27,7 +27,7 @@ unsigned int shader_program;
unsigned int vao; unsigned int vao;
unsigned int uniform_transform; unsigned int uniform_transform;
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
static GLuint load_shader() { static GLuint load_shader() {
#ifndef OPENCV_V4D_USE_ES3 #ifndef OPENCV_V4D_USE_ES3
@ -174,7 +174,6 @@ static void render_scene() {
glUniformMatrix4fv(uniform_transform, 1, GL_FALSE, transform.val); glUniformMatrix4fv(uniform_transform, 1, GL_FALSE, transform.val);
glBindVertexArray(vao); glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_SHORT, NULL); glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_SHORT, NULL);
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
@ -205,25 +204,22 @@ static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
static bool iteration() { static bool iteration() {
using namespace cv::v4d; using namespace cv::v4d;
// if(!v4d->capture())
// return false;
//Render using OpenGL //Render using OpenGL
v4d->gl(render_scene); window->gl(render_scene);
//To slow for WASM //To slow for WASM
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL //Aquire the frame buffer for use by OpenCL
v4d->fb([&](cv::UMat& frameBuffer) { window->fb([&](cv::UMat& frameBuffer) {
//Glow effect (OpenCL) //Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE); glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE);
}); });
#endif #endif
v4d->write(); window->write();
// std::this_thread::sleep_for(std::chrono::milliseconds(10));
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
@ -232,19 +228,16 @@ int main(int argc, char** argv) {
int main() { int main() {
#endif #endif
using namespace cv::v4d; using namespace cv::v4d;
v4d = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Cube Demo", OFFSCREEN); window = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Cube Demo", OFFSCREEN);
v4d->printSystemInfo(); window->printSystemInfo();
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), FPS, Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), FPS,
cv::Size(WIDTH, HEIGHT)); cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
//#else
// Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
// v4d->setSource(src);
#endif #endif
v4d->gl(init_scene); window->gl(init_scene);
v4d->run(iteration); window->run(iteration);
return 0; return 0;
} }

@ -45,13 +45,13 @@ using std::string;
using std::vector; using std::vector;
using std::istringstream; using std::istringstream;
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
vector<string> lines; vector<string> lines;
bool update_stars = true; bool update_stars = true;
bool update_perspective = true; bool update_perspective = true;
static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain) { static void setup_gui(cv::Ptr<cv::v4d::V4D> main) {
v4dMain->nanogui([&](cv::v4d::FormHelper& form){ main->nanogui([&](cv::v4d::FormHelper& form){
form.makeDialog(5, 30, "Effect"); form.makeDialog(5, 30, "Effect");
form.makeGroup("Text Crawl"); form.makeGroup("Text Crawl");
form.makeFormVariable("Font Size", font_size, 1.0f, 100.0f, true, "pt", "Font size of the text crawl"); form.makeFormVariable("Font Size", font_size, 1.0f, 100.0f, true, "pt", "Font size of the text crawl");
@ -96,11 +96,11 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain) {
form.makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display"); form.makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display");
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() { form.makeButton("Fullscreen", [=]() {
v4dMain->setFullscreen(!v4dMain->isFullscreen()); main->setFullscreen(!main->isFullscreen());
}); });
#endif #endif
form.makeButton("Offscreen", [=]() { form.makeButton("Offscreen", [=]() {
v4dMain->setVisible(!v4dMain->isVisible()); main->setVisible(!main->isVisible());
}); });
}); });
} }
@ -123,7 +123,7 @@ static bool iteration() {
int32_t translateY = HEIGHT - cnt; int32_t translateY = HEIGHT - cnt;
if(update_stars) { if(update_stars) {
v4d->nvg([&](const cv::Size& sz) { window->nvg([&](const cv::Size& sz) {
using namespace cv::v4d::nvg; using namespace cv::v4d::nvg;
clear(); clear();
@ -139,7 +139,7 @@ static bool iteration() {
} }
}); });
v4d->fb([&](cv::UMat& frameBuffer){ window->fb([&](cv::UMat& frameBuffer){
frameBuffer.copyTo(stars); frameBuffer.copyTo(stars);
}); });
update_stars = false; update_stars = false;
@ -156,7 +156,7 @@ static bool iteration() {
update_perspective = false; update_perspective = false;
} }
v4d->nvg([&](const cv::Size& sz) { window->nvg([&](const cv::Size& sz) {
using namespace cv::v4d::nvg; using namespace cv::v4d::nvg;
clear(); clear();
fontSize(font_size); fontSize(font_size);
@ -175,7 +175,7 @@ static bool iteration() {
} }
}); });
v4d->fb([&](cv::UMat& framebuffer) { window->fb([&](cv::UMat& framebuffer) {
//Pseudo 3D text effect. //Pseudo 3D text effect.
cv::warpPerspective(framebuffer, warped, tm, framebuffer.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar()); cv::warpPerspective(framebuffer, warped, tm, framebuffer.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar());
//Combine layers //Combine layers
@ -187,7 +187,7 @@ static bool iteration() {
cnt = 0; cnt = 0;
} }
v4d->write(); window->write();
++cnt; ++cnt;
//Wrap the cnt around if it becomes to big. //Wrap the cnt around if it becomes to big.
@ -195,18 +195,18 @@ static bool iteration() {
cnt = 0; cnt = 0;
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
int main() { int main() {
try { try {
using namespace cv::v4d; using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Font Demo", OFFSCREEN, true); window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Font Demo", OFFSCREEN, true);
if(!OFFSCREEN) { if(!OFFSCREEN) {
setup_gui(v4d); setup_gui(window);
} }
v4d->printSystemInfo(); window->printSystemInfo();
//The text to display //The text to display
string txt = cv::getBuildInformation(); string txt = cv::getBuildInformation();
@ -219,10 +219,10 @@ int main() {
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), FPS, cv::Size(WIDTH, HEIGHT)); Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), FPS, cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
#endif #endif
v4d->run(iteration); window->run(iteration);
} catch(std::exception& ex) { } catch(std::exception& ex) {
cerr << "Exception: " << ex.what() << endl; cerr << "Exception: " << ex.what() << endl;
} }

@ -15,7 +15,7 @@ constexpr const char *OUTPUT_FILENAME = "nanovg-demo.mkv";
using std::cerr; using std::cerr;
using std::endl; using std::endl;
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
static void draw_color_wheel(float x, float y, float w, float h, float hue) { static void draw_color_wheel(float x, float y, float w, float h, float hue) {
//color wheel drawing code taken from https://github.com/memononen/nanovg/blob/master/example/demo.c //color wheel drawing code taken from https://github.com/memononen/nanovg/blob/master/example/demo.c
@ -128,14 +128,14 @@ static bool iteration() {
static cv::UMat hueChannel; static cv::UMat hueChannel;
//we use frame count to calculated the current hue //we use frame count to calculated the current hue
float time = v4d->frameCount() / 60.0; float time = window->frameCount() / 60.0;
//nanovg hue fading between 0.0f and 255.0f //nanovg hue fading between 0.0f and 255.0f
float hue = (sinf(time * 0.12f) + 1.0f) * 127.5; float hue = (sinf(time * 0.12f) + 1.0f) * 127.5;
if (!v4d->capture()) if (!window->capture())
return false; return false;
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameBuffer, rgb, cv::COLOR_BGRA2RGB); cvtColor(frameBuffer, rgb, cv::COLOR_BGRA2RGB);
}); });
@ -153,20 +153,20 @@ static bool iteration() {
cv::cvtColor(hsv, rgb, cv::COLOR_HSV2RGB_FULL); cv::cvtColor(hsv, rgb, cv::COLOR_HSV2RGB_FULL);
//Color-conversion from RGB to BGRA. (OpenCL) //Color-conversion from RGB to BGRA. (OpenCL)
v4d->fb([&](cv::UMat &frameBuffer) { window->fb([&](cv::UMat &frameBuffer) {
cv::cvtColor(rgb, frameBuffer, cv::COLOR_RGB2BGRA); cv::cvtColor(rgb, frameBuffer, cv::COLOR_RGB2BGRA);
}); });
//Render using nanovg //Render using nanovg
v4d->nvg([&](const cv::Size &sz) { window->nvg([&](const cv::Size &sz) {
hue = ((170 + uint8_t(255 - hue))) % 255; hue = ((170 + uint8_t(255 - hue))) % 255;
draw_color_wheel(sz.width - 300, sz.height - 300, 250.0f, 250.0f, hue); draw_color_wheel(sz.width - 300, sz.height - 300, 250.0f, 250.0f, hue);
}); });
v4d->write(); window->write();
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
@ -179,20 +179,20 @@ int main(int argc, char **argv) {
int main() { int main() {
#endif #endif
using namespace cv::v4d; using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "NanoVG Demo", OFFSCREEN); window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "NanoVG Demo", OFFSCREEN);
v4d->printSystemInfo(); window->printSystemInfo();
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]); Source src = makeCaptureSource(argv[1]);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), src.fps(), cv::Size(WIDTH, HEIGHT)); Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), src.fps(), cv::Size(WIDTH, HEIGHT));
v4d->setSource(src); window->setSource(src);
v4d->setSink(sink); window->setSink(sink);
#else #else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d); Source src = makeCaptureSource(WIDTH, HEIGHT, window);
v4d->setSource(src); window->setSource(src);
#endif #endif
v4d->run(iteration); window->run(iteration);
return 0; return 0;
} }

@ -5,6 +5,12 @@
#include <opencv2/v4d/v4d.hpp> #include <opencv2/v4d/v4d.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/optflow.hpp>
#include <opencv2/core/ocl.hpp>
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include <set> #include <set>
@ -12,12 +18,6 @@
#include <thread> #include <thread>
#include <random> #include <random>
#include <opencv2/features2d.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/optflow.hpp>
#include <opencv2/core/ocl.hpp>
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::vector; using std::vector;
@ -47,9 +47,9 @@ constexpr const char* OUTPUT_FILENAME = "optflow-demo.mkv";
#endif #endif
constexpr bool OFFSCREEN = false; constexpr bool OFFSCREEN = false;
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
cv::Ptr<cv::v4d::V4D> v4d2; cv::Ptr<cv::v4d::V4D> menuWindow;
#endif #endif
/** Visualization parameters **/ /** Visualization parameters **/
@ -306,8 +306,8 @@ static void composite_layers(cv::UMat& background, const cv::UMat& foreground, c
cv::add(background, post, dst); cv::add(background, post, dst);
} }
static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain, cv::Ptr<cv::v4d::V4D> v4dMenu) { static void setup_gui(cv::Ptr<cv::v4d::V4D> main, cv::Ptr<cv::v4d::V4D> menu) {
v4dMain->nanogui([&](cv::v4d::FormHelper& form){ main->nanogui([&](cv::v4d::FormHelper& form){
form.makeDialog(5, 30, "Effects"); form.makeDialog(5, 30, "Effects");
form.makeGroup("Foreground"); form.makeGroup("Foreground");
@ -378,22 +378,22 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain, cv::Ptr<cv::v4d::V4D> v4dMe
form.makeFormVariable("Threshold Diff", scene_change_thresh_diff, 0.1f, 1.0f, true, "", "Difference of peak thresholds. Lowering it makes detection more sensitive"); form.makeFormVariable("Threshold Diff", scene_change_thresh_diff, 0.1f, 1.0f, true, "", "Difference of peak thresholds. Lowering it makes detection more sensitive");
}); });
v4dMenu->nanogui([&](cv::v4d::FormHelper& form){ menu->nanogui([&](cv::v4d::FormHelper& form){
form.makeDialog(8, 16, "Display"); form.makeDialog(8, 16, "Display");
form.makeGroup("Display"); form.makeGroup("Display");
form.makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display"); form.makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display");
form.makeFormVariable("Stetch", stretch, "Stretch the frame buffer to the window size")->set_callback([=](const bool &s) { form.makeFormVariable("Stetch", stretch, "Stretch the frame buffer to the window size")->set_callback([=](const bool &s) {
v4dMain->setFrameBufferScaling(s); main->setFrameBufferScaling(s);
}); });
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() { form.makeButton("Fullscreen", [=]() {
v4dMain->setFullscreen(!v4dMain->isFullscreen()); main->setFullscreen(!main->isFullscreen());
}); });
form.makeButton("Offscreen", [=]() { form.makeButton("Offscreen", [=]() {
v4dMain->setVisible(!v4dMain->isVisible()); main->setVisible(!main->isVisible());
}); });
#endif #endif
}); });
@ -402,18 +402,18 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain, cv::Ptr<cv::v4d::V4D> v4dMe
static bool iteration() { static bool iteration() {
//BGRA //BGRA
static cv::UMat background, down; static cv::UMat background, down;
static cv::UMat foreground(v4d->framebufferSize(), CV_8UC4, cv::Scalar::all(0)); static cv::UMat foreground(window->framebufferSize(), CV_8UC4, cv::Scalar::all(0));
//RGB //RGB
static cv::UMat menuFrame; static cv::UMat menuFrame;
//GREY //GREY
static cv::UMat downPrevGrey, downNextGrey, downMotionMaskGrey; static cv::UMat downPrevGrey, downNextGrey, downMotionMaskGrey;
static vector<cv::Point2f> detectedPoints; static vector<cv::Point2f> detectedPoints;
if(!v4d->capture()) if(!window->capture())
return false; return false;
v4d->fb([&](cv::UMat& frameBuffer) { window->fb([&](cv::UMat& frameBuffer) {
cv::resize(frameBuffer, down, cv::Size(v4d->framebufferSize().width * fg_scale, v4d->framebufferSize().height * fg_scale)); cv::resize(frameBuffer, down, cv::Size(window->framebufferSize().width * fg_scale, window->framebufferSize().height * fg_scale));
frameBuffer.copyTo(background); frameBuffer.copyTo(background);
}); });
@ -423,7 +423,7 @@ static bool iteration() {
//Detect trackable points in the motion mask //Detect trackable points in the motion mask
detect_points(downMotionMaskGrey, detectedPoints); detect_points(downMotionMaskGrey, detectedPoints);
v4d->nvg([&]() { window->nvg([&]() {
cv::v4d::nvg::clear(); cv::v4d::nvg::clear();
if (!downPrevGrey.empty()) { 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. //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.
@ -437,7 +437,7 @@ static bool iteration() {
downPrevGrey = downNextGrey.clone(); downPrevGrey = downNextGrey.clone();
v4d->fb([&](cv::UMat& frameBuffer){ window->fb([&](cv::UMat& frameBuffer){
cv::resize(foreground, foreground, frameBuffer.size()); cv::resize(foreground, foreground, frameBuffer.size());
//Put it all together (OpenCL) //Put it all together (OpenCL)
composite_layers(background, foreground, frameBuffer, frameBuffer, GLOW_KERNEL_SIZE, fg_loss, background_mode, post_proc_mode); composite_layers(background, foreground, frameBuffer, frameBuffer, GLOW_KERNEL_SIZE, fg_loss, background_mode, post_proc_mode);
@ -447,16 +447,16 @@ static bool iteration() {
}); });
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
v4d->write(); window->write();
v4d2->feed(menuFrame); menuWindow->feed(menuFrame);
if(!v4d2->display()) if(!menuWindow->display())
return false; return false;
#endif #endif
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -469,35 +469,35 @@ int main() {
#endif #endif
try { try {
using namespace cv::v4d; using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Sparse Optical Flow Demo", OFFSCREEN); window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Sparse Optical Flow Demo", OFFSCREEN);
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
v4d2 = V4D::make(cv::Size(240, 360), cv::Size(), "Display Settings", OFFSCREEN); menuWindow = V4D::make(cv::Size(240, 360), cv::Size(), "Display Settings", OFFSCREEN);
#endif #endif
v4d->printSystemInfo(); window->printSystemInfo();
if (!OFFSCREEN) { if (!OFFSCREEN) {
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
setup_gui(v4d, v4d2); setup_gui(window, menuWindow);
v4d2->setResizable(false); menuWindow->setResizable(false);
#else #else
setup_gui(v4d, v4d); setup_gui(window, window);
#endif #endif
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]); Source src = makeCaptureSource(argv[1]);
v4d->setSource(src); window->setSource(src);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'),
src.fps(), cv::Size(WIDTH, HEIGHT)); src.fps(), cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
#else #else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d); Source src = makeCaptureSource(WIDTH, HEIGHT, window);
v4d->setSource(src); window->setSource(src);
#endif #endif
v4d->run(iteration); window->run(iteration);
} catch (std::exception& ex) { } catch (std::exception& ex) {
cerr << ex.what() << endl; cerr << ex.what() << endl;
} }

@ -14,8 +14,8 @@ constexpr unsigned int HEIGHT = 720;
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT)); const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
constexpr unsigned int DOWNSIZE_WIDTH = 640; constexpr unsigned int DOWNSIZE_WIDTH = 640;
constexpr unsigned int DOWNSIZE_HEIGHT = 360; constexpr unsigned int DOWNSIZE_HEIGHT = 360;
constexpr double WIDTH_FACTOR = double(WIDTH) / DOWNSIZE_WIDTH; constexpr double WIDTH_SCALE = double(WIDTH) / DOWNSIZE_WIDTH;
constexpr double HEIGHT_FACTOR = double(HEIGHT) / DOWNSIZE_HEIGHT; constexpr double HEIGHT_SCALE = double(HEIGHT) / DOWNSIZE_HEIGHT;
constexpr bool OFFSCREEN = false; constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
constexpr const char* OUTPUT_FILENAME = "pedestrian-demo.mkv"; constexpr const char* OUTPUT_FILENAME = "pedestrian-demo.mkv";
@ -29,7 +29,7 @@ using std::endl;
using std::vector; using std::vector;
using std::string; using std::string;
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
cv::HOGDescriptor hog; cv::HOGDescriptor hog;
//adapted from cv::dnn_objdetect::InferBbox //adapted from cv::dnn_objdetect::InferBbox
@ -128,10 +128,10 @@ static bool iteration() {
static bool redetect = true; static bool redetect = true;
if(!v4d->capture()) if(!window->capture())
return false; return false;
v4d->fb([&](cv::UMat& frameBuffer){ window->fb([&](cv::UMat& frameBuffer){
cvtColor(frameBuffer,videoFrame,cv::COLOR_BGRA2RGB); cvtColor(frameBuffer,videoFrame,cv::COLOR_BGRA2RGB);
cv::resize(videoFrame, videoFrameDown, cv::Size(DOWNSIZE_WIDTH, DOWNSIZE_HEIGHT)); cv::resize(videoFrame, videoFrameDown, cv::Size(DOWNSIZE_WIDTH, DOWNSIZE_HEIGHT));
}); });
@ -176,29 +176,29 @@ static bool iteration() {
} }
} }
v4d->nvg([&](const cv::Size& sz) { window->nvg([&](const cv::Size& sz) {
using namespace cv::v4d::nvg; using namespace cv::v4d::nvg;
clear(); clear();
beginPath(); beginPath();
strokeWidth(std::fmax(2.0, sz.width / 960.0)); strokeWidth(std::fmax(2.0, sz.width / 960.0));
strokeColor(cv::v4d::colorConvert(cv::Scalar(0, 127, 255, 200), cv::COLOR_HLS2BGR)); strokeColor(cv::v4d::colorConvert(cv::Scalar(0, 127, 255, 200), cv::COLOR_HLS2BGR));
float width = tracked.width * WIDTH_FACTOR; float width = tracked.width * WIDTH_SCALE;
float height = tracked.height * HEIGHT_FACTOR; float height = tracked.height * HEIGHT_SCALE;
float cx = tracked.x * WIDTH_FACTOR + (width / 2.0f); float cx = tracked.x * WIDTH_SCALE + (width / 2.0f);
float cy = tracked.y * HEIGHT_FACTOR + (height / 2.0f); float cy = tracked.y * HEIGHT_SCALE + (height / 2.0f);
ellipse(cx, cy, width / 2.0f, height / 2.0f); ellipse(cx, cy, width / 2.0f, height / 2.0f);
stroke(); stroke();
}); });
v4d->fb([&](cv::UMat& frameBuffer){ window->fb([&](cv::UMat& frameBuffer){
//Put it all together //Put it all together
composite_layers(background, frameBuffer, frameBuffer, BLUR_KERNEL_SIZE); composite_layers(background, frameBuffer, frameBuffer, BLUR_KERNEL_SIZE);
}); });
v4d->write(); window->write();
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
@ -211,24 +211,24 @@ int main(int argc, char **argv) {
int main() { int main() {
#endif #endif
using namespace cv::v4d; using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Pedestrian Demo", OFFSCREEN); window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Pedestrian Demo", OFFSCREEN);
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector()); hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
v4d->printSystemInfo(); window->printSystemInfo();
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]); Source src = makeCaptureSource(argv[1]);
v4d->setSource(src); window->setSource(src);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'),
src.fps(), cv::Size(WIDTH, HEIGHT)); src.fps(), cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
#else #else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d); Source src = makeCaptureSource(WIDTH, HEIGHT, window);
v4d->setSource(src); window->setSource(src);
#endif #endif
v4d->run(iteration); window->run(iteration);
return 0; return 0;
} }

@ -1,5 +1,4 @@
#include <opencv2/v4d/v4d.hpp> #include <opencv2/v4d/v4d.hpp>
#include "../src/detail/framebuffercontext.hpp"
using namespace cv; using namespace cv;
using namespace cv::v4d; using namespace cv::v4d;
@ -13,7 +12,6 @@ int main() {
}); });
window->run([=]() { window->run([=]() {
window->gl([]() { window->gl([]() {
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
//Clears the screen //Clears the screen
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
}); });

@ -18,7 +18,7 @@ constexpr double FPS = 60;
constexpr const char* OUTPUT_FILENAME = "shader-demo.mkv"; constexpr const char* OUTPUT_FILENAME = "shader-demo.mkv";
#endif #endif
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
int glow_kernel_size = std::max(int(DIAG / 200 % 2 == 0 ? DIAG / 200 + 1 : DIAG / 200), 1); int glow_kernel_size = std::max(int(DIAG / 200 % 2 == 0 ? DIAG / 200 + 1 : DIAG / 200), 1);
@ -153,6 +153,7 @@ static void load_shader() {
outColor = vec4(base_color[0] * iterations * cb, base_color[1] * iterations * cb, base_color[2] * iterations * cb, base_color[3]); outColor = vec4(base_color[0] * iterations * cb, base_color[1] * iterations * cb, base_color[2] * iterations * cb, base_color[3]);
} else { } else {
gl_FragDepth = -1.0;
outColor = vec4(0,0,0,0); outColor = vec4(0,0,0,0);
} }
} }
@ -192,8 +193,6 @@ static void init_scene(const cv::Size& sz) {
} }
static void render_scene() { static void render_scene() {
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
if (zoom >= 1) { if (zoom >= 1) {
zoom_incr = -0.01; zoom_incr = -0.01;
iterations = 0; iterations = 0;
@ -313,27 +312,27 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain) {
} }
static bool iteration() { static bool iteration() {
if(!v4d->capture()) if(!window->capture())
return false; return false;
//Render using OpenGL //Render using OpenGL
v4d->gl(render_scene); window->gl(render_scene);
//To slow for WASM but works //To slow for WASM but works
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL //Aquire the frame buffer for use by OpenCL
v4d->fb([](cv::UMat& frameBuffer) { window->fb([](cv::UMat& frameBuffer) {
//Glow effect (OpenCL) //Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, glow_kernel_size); glow_effect(frameBuffer, frameBuffer, glow_kernel_size);
}); });
#endif #endif
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
v4d->write(); window->write();
#endif #endif
++iterations; ++iterations;
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
@ -347,28 +346,28 @@ int main() {
#endif #endif
try { try {
using namespace cv::v4d; using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Shader Demo", OFFSCREEN); window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Shader Demo", OFFSCREEN);
if (!OFFSCREEN) { if (!OFFSCREEN) {
setup_gui(v4d); setup_gui(window);
} }
v4d->printSystemInfo(); window->printSystemInfo();
v4d->gl(init_scene); window->gl(init_scene);
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]); Source src = makeCaptureSource(argv[1]);
v4d->setSource(src); window->setSource(src);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'),
FPS, cv::Size(WIDTH, HEIGHT)); FPS, cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
#else #else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d); Source src = makeCaptureSource(WIDTH, HEIGHT, window);
v4d->setSource(src); window->setSource(src);
#endif #endif
v4d->run(iteration); window->run(iteration);
} catch (std::exception& ex) { } catch (std::exception& ex) {
cerr << "Exception: " << ex.what() << endl; cerr << "Exception: " << ex.what() << endl;
} }

@ -6,18 +6,19 @@ using namespace cv::v4d;
int main() { int main() {
Ptr<V4D> window = V4D::make(Size(1280, 720), cv::Size(), "Vector Graphics"); Ptr<V4D> window = V4D::make(Size(1280, 720), cv::Size(), "Vector Graphics");
//Display the framebuffer in the native window in an endless loop //Render the framebuffer in the native window in an endless loop
window->run([=]() { window->run([=]() {
//Creates a NanoVG context and draws eyes //Creates a NanoVG context and draws eyes
window->nvg([](const Size& sz) { window->nvg([](const Size& sz) {
//Calls from this namespace may only be used inside a nvg context //Calls from this namespace may only be used inside a nvg context
using namespace cv::v4d::nvg; using namespace cv::v4d::nvg;
clear(); clear();
float t = cv::getTickCount(); float t = cv::getTickCount() / cv::getTickFrequency();
float x = 0; float x = 0;
float y = 0; float y = 0;
float w = sz.width / 4; float w = sz.width / 4;
float h = sz.height / 4; float h = sz.height / 4;
translate((sz.width / 2.0f) - (w / 2.0f), (sz.height / 2.0f) - (h / 2.0f));
float mx = w / 2.0; float mx = w / 2.0;
float my = h / 2.0; float my = h / 2.0;
Paint gloss, bg; Paint gloss, bg;

@ -7,18 +7,20 @@ using namespace cv::v4d;
int main() { int main() {
Ptr<V4D> window = V4D::make(Size(1280, 720), cv::Size(), "Vector Graphics and Framebuffer"); Ptr<V4D> window = V4D::make(Size(1280, 720), cv::Size(), "Vector Graphics and Framebuffer");
//Display the framebuffer in the native window in an endless loop //Render the framebuffer in the native window in an endless loop
window->run([=]() { window->run([=]() {
//Creates a NanoVG context and draws eyes //Creates a NanoVG context and draws eyes
window->nvg([](const Size& sz) { window->nvg([](const Size& sz) {
//Calls from this namespace may only be used inside a nvg context //Calls from this namespace may only be used inside a nvg context
using namespace cv::v4d::nvg; using namespace cv::v4d::nvg;
clear(); clear();
float t = cv::getTickCount();
float t = cv::getTickCount() / cv::getTickFrequency();
float x = 0; float x = 0;
float y = 0; float y = 0;
float w = sz.width / 4; float w = sz.width / 4;
float h = sz.height / 4; float h = sz.height / 4;
translate((sz.width / 2.0f) - (w / 2.0f), (sz.height / 2.0f) - (h / 2.0f));
float mx = w / 2.0; float mx = w / 2.0;
float my = h / 2.0; float my = h / 2.0;
Paint gloss, bg; Paint gloss, bg;
@ -91,7 +93,6 @@ int main() {
}); });
window->fb([](UMat& framebuffer) { window->fb([](UMat& framebuffer) {
// cerr << "COUNT1:" << cv::v4d::detail::cnz(framebuffer) << endl;
//Heavily blurs the eyes using a cheap boxFilter //Heavily blurs the eyes using a cheap boxFilter
boxFilter(framebuffer, framebuffer, -1, Size(15, 15), Point(-1,-1), true, BORDER_REPLICATE); boxFilter(framebuffer, framebuffer, -1, Size(15, 15), Point(-1,-1), true, BORDER_REPLICATE);
}); });

@ -25,7 +25,7 @@ unsigned int shader_program;
unsigned int vao; unsigned int vao;
unsigned int uniform_transform; unsigned int uniform_transform;
cv::Ptr<cv::v4d::V4D> v4d; cv::Ptr<cv::v4d::V4D> window;
static GLuint load_shader() { static GLuint load_shader() {
#ifndef OPENCV_V4D_USE_ES3 #ifndef OPENCV_V4D_USE_ES3
@ -134,8 +134,6 @@ static void init_scene() {
} }
static void render_scene() { static void render_scene() {
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program); glUseProgram(shader_program);
float angle = fmod(double(cv::getTickCount()) / double(cv::getTickFrequency()), 2 * M_PI); float angle = fmod(double(cv::getTickCount()) / double(cv::getTickFrequency()), 2 * M_PI);
@ -188,25 +186,25 @@ static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
static bool iteration() { static bool iteration() {
using namespace cv::v4d; using namespace cv::v4d;
if(!v4d->capture()) if(!window->capture())
return false; return false;
//Render using OpenGL //Render using OpenGL
v4d->gl(render_scene); window->gl(render_scene);
//to slow for wasm //to slow for wasm
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL //Aquire the frame buffer for use by OpenCL
v4d->fb([&](cv::UMat& frameBuffer) { window->fb([&](cv::UMat& frameBuffer) {
//Glow effect (OpenCL) //Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE); glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE);
}); });
#endif #endif
v4d->write(); window->write();
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed. //If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
return v4d->display(); return window->display();
} }
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
@ -219,24 +217,24 @@ int main(int argc, char** argv) {
int main() { int main() {
#endif #endif
using namespace cv::v4d; using namespace cv::v4d;
v4d = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Video Demo", OFFSCREEN); window = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Video Demo", OFFSCREEN);
v4d->printSystemInfo(); window->printSystemInfo();
#ifndef __EMSCRIPTEN__ #ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]); Source src = makeCaptureSource(argv[1]);
v4d->setSource(src); window->setSource(src);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'),
src.fps(), cv::Size(WIDTH, HEIGHT)); src.fps(), cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink); window->setSink(sink);
#else #else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d); Source src = makeCaptureSource(WIDTH, HEIGHT, window);
v4d->setSource(src); window->setSource(src);
#endif #endif
v4d->gl(init_scene); window->gl(init_scene);
v4d->run(iteration); window->run(iteration);
return 0; return 0;
} }

@ -28,6 +28,13 @@ void GLContext::render(std::function<void(const cv::Size&)> fn) {
{ {
FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER); FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
#ifdef __EMSCRIPTEN__
GLfloat cColor[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, cColor);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(cColor[0], cColor[1], cColor[2], cColor[3]);
#endif
fn(fbCtx().size()); fn(fbCtx().size());
} }
if(!fbCtx().isShared()) { if(!fbCtx().isShared()) {

@ -26,6 +26,13 @@ void NanoguiContext::render() {
{ {
FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER); FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
#ifdef __EMSCRIPTEN__
GLfloat cColor[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, cColor);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(cColor[0], cColor[1], cColor[2], cColor[3]);
#endif
screen().draw_widgets(); screen().draw_widgets();
} }
{ {
@ -62,9 +69,6 @@ void NanoguiContext::updateFps(bool print, bool graphical) {
NanoVGContext::render([this](const Size sz){ NanoVGContext::render([this](const Size sz){
CV_UNUSED(sz); CV_UNUSED(sz);
using namespace cv::v4d::nvg; using namespace cv::v4d::nvg;
#ifdef __EMSCRIPTEN__
clear({0.0,0.0,0.0,0.0});
#endif
string txt = "FPS: " + std::to_string(fps_); string txt = "FPS: " + std::to_string(fps_);
beginPath(); beginPath();
roundedRect(5, 5, 15 * txt.size() + 5, 30, 5); roundedRect(5, 5, 15 * txt.size() + 5, 30, 5);

@ -51,6 +51,13 @@ void NanoVGContext::render(std::function<void(const cv::Size&)> fn) {
{ {
FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER); FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
#ifdef __EMSCRIPTEN__
GLfloat cColor[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, cColor);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(cColor[0], cColor[1], cColor[2], cColor[3]);
#endif
NanoVGContext::Scope nvgScope(*this); NanoVGContext::Scope nvgScope(*this);
cv::v4d::nvg::detail::NVG::initializeContext(context_); cv::v4d::nvg::detail::NVG::initializeContext(context_);
fn(fbCtx().size()); fn(fbCtx().size());

Loading…
Cancel
Save