brushing up demos & examples

pull/3471/head
kallaballa 2 years ago
parent 2522685b13
commit 20e6a4cb7a
  1. 71
      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>
#include <opencv2/v4d/v4d.hpp>
#include <vector>
#include <string>
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/face.hpp>
#include <opencv2/stitching/detail/blenders.hpp>
#include <opencv2/tracking.hpp>
#include <vector>
#include <string>
using std::cerr;
using std::endl;
using std::vector;
@ -27,7 +26,8 @@ using std::string;
/** Application parameters **/
constexpr unsigned int WIDTH = 1280;
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;
#ifndef __EMSCRIPTEN__
constexpr const char *OUTPUT_FILENAME = "beauty-demo.mkv";
@ -48,7 +48,7 @@ bool side_by_side = false;
bool stretch = false;
#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::detail::MultiBandBlender blender(false, 5); //Blender (used to put the different face parts back together)
@ -204,12 +204,17 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v) {
form.makeGroup("Display");
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");
#ifndef __EMSCRIPTEN__
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__
form.makeButton("Fullscreen", [=]() {
v->setFullscreen(!v->isFullscreen());
});
#endif
#endif
form.makeButton("Offscreen", [=]() {
v->setVisible(!v->isVisible());
});
@ -245,14 +250,14 @@ static bool iteration() {
#endif
//Face detector
#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
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
//BGR
static cv::UMat input, down, blurred, contrast, faceOval, eyesAndLips, skin;
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());
//GREY
static cv::UMat faceSkinMaskGrey, eyesAndLipsMaskGrey, backgroundMaskGrey;
@ -270,15 +275,15 @@ static bool iteration() {
//FaceFeatures of all faces found
static vector<FaceFeatures> featuresList;
if (!v4d->capture())
if (!window->capture())
return false;
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameBuffer, input, cv::COLOR_BGRA2BGR);
});
//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();
faceRects.clear();
@ -313,22 +318,22 @@ static bool iteration() {
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_face_oval_mask(featuresList);
});
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
//Convert/Copy the mask
cvtColor(frameBuffer, faceOval, cv::COLOR_BGRA2GRAY);
});
v4d->nvg([&]() {
window->nvg([&]() {
//Draw eyes eyes and lips areas of the first face
draw_face_eyes_and_lips_mask(featuresList);
});
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
//Convert/Copy the mask
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)));
}
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA);
});
} else {
@ -380,17 +385,17 @@ static bool iteration() {
input.copyTo(frameOut);
}
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameOut, frameBuffer, cv::COLOR_BGR2BGRA);
});
}
#ifndef __EMSCRIPTEN__
v4d->write();
window->write();
#endif
//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) {
cerr << ex.what() << endl;
return false;
@ -401,35 +406,35 @@ static bool iteration() {
#ifndef __EMSCRIPTEN__
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: beauty-demo <input-video-file>" << endl;
cerr << "Usage: beauty-demo <input-video-file>" << endl;
exit(1);
}
#else
int main() {
#endif
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");
v4d->setFrameBufferScaling(stretch);
window->setFrameBufferScaling(stretch);
if (!OFFSCREEN) {
setup_gui(v4d);
setup_gui(window);
}
v4d->printSystemInfo();
window->printSystemInfo();
#ifndef __EMSCRIPTEN__
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));
v4d->setSink(sink);
window->setSink(sink);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
v4d->setSource(src);
Source src = makeCaptureSource(WIDTH, HEIGHT, window);
window->setSource(src);
#endif
v4d->run(iteration);
window->run(iteration);
return 0;
}

@ -4,7 +4,7 @@
// Copyright Amir Hassan (kallaballa) <amir@viel-zu.org>
#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 HEIGHT = 720;
@ -27,7 +27,7 @@ unsigned int shader_program;
unsigned int vao;
unsigned int uniform_transform;
cv::Ptr<cv::v4d::V4D> v4d;
cv::Ptr<cv::v4d::V4D> window;
static GLuint load_shader() {
#ifndef OPENCV_V4D_USE_ES3
@ -174,7 +174,6 @@ static void render_scene() {
glUniformMatrix4fv(uniform_transform, 1, GL_FALSE, transform.val);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_SHORT, NULL);
}
#ifndef __EMSCRIPTEN__
@ -205,25 +204,22 @@ static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
static bool iteration() {
using namespace cv::v4d;
// if(!v4d->capture())
// return false;
//Render using OpenGL
v4d->gl(render_scene);
window->gl(render_scene);
//To slow for WASM
#ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL
v4d->fb([&](cv::UMat& frameBuffer) {
window->fb([&](cv::UMat& frameBuffer) {
//Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE);
});
#endif
v4d->write();
// std::this_thread::sleep_for(std::chrono::milliseconds(10));
window->write();
//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__
@ -232,19 +228,16 @@ int main(int argc, char** argv) {
int main() {
#endif
using namespace cv::v4d;
v4d = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Cube Demo", OFFSCREEN);
v4d->printSystemInfo();
window = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Cube Demo", OFFSCREEN);
window->printSystemInfo();
#ifndef __EMSCRIPTEN__
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), FPS,
cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink);
//#else
// Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
// v4d->setSource(src);
window->setSink(sink);
#endif
v4d->gl(init_scene);
v4d->run(iteration);
window->gl(init_scene);
window->run(iteration);
return 0;
}

@ -45,13 +45,13 @@ using std::string;
using std::vector;
using std::istringstream;
cv::Ptr<cv::v4d::V4D> v4d;
cv::Ptr<cv::v4d::V4D> window;
vector<string> lines;
bool update_stars = true;
bool update_perspective = true;
static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain) {
v4dMain->nanogui([&](cv::v4d::FormHelper& form){
static void setup_gui(cv::Ptr<cv::v4d::V4D> main) {
main->nanogui([&](cv::v4d::FormHelper& form){
form.makeDialog(5, 30, "Effect");
form.makeGroup("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");
#ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() {
v4dMain->setFullscreen(!v4dMain->isFullscreen());
main->setFullscreen(!main->isFullscreen());
});
#endif
form.makeButton("Offscreen", [=]() {
v4dMain->setVisible(!v4dMain->isVisible());
main->setVisible(!main->isVisible());
});
});
}
@ -123,7 +123,7 @@ static bool iteration() {
int32_t translateY = HEIGHT - cnt;
if(update_stars) {
v4d->nvg([&](const cv::Size& sz) {
window->nvg([&](const cv::Size& sz) {
using namespace cv::v4d::nvg;
clear();
@ -139,7 +139,7 @@ static bool iteration() {
}
});
v4d->fb([&](cv::UMat& frameBuffer){
window->fb([&](cv::UMat& frameBuffer){
frameBuffer.copyTo(stars);
});
update_stars = false;
@ -156,7 +156,7 @@ static bool iteration() {
update_perspective = false;
}
v4d->nvg([&](const cv::Size& sz) {
window->nvg([&](const cv::Size& sz) {
using namespace cv::v4d::nvg;
clear();
fontSize(font_size);
@ -175,7 +175,7 @@ static bool iteration() {
}
});
v4d->fb([&](cv::UMat& framebuffer) {
window->fb([&](cv::UMat& framebuffer) {
//Pseudo 3D text effect.
cv::warpPerspective(framebuffer, warped, tm, framebuffer.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar());
//Combine layers
@ -187,7 +187,7 @@ static bool iteration() {
cnt = 0;
}
v4d->write();
window->write();
++cnt;
//Wrap the cnt around if it becomes to big.
@ -195,18 +195,18 @@ static bool iteration() {
cnt = 0;
//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() {
try {
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) {
setup_gui(v4d);
setup_gui(window);
}
v4d->printSystemInfo();
window->printSystemInfo();
//The text to display
string txt = cv::getBuildInformation();
@ -219,10 +219,10 @@ int main() {
#ifndef __EMSCRIPTEN__
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), FPS, cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink);
window->setSink(sink);
#endif
v4d->run(iteration);
window->run(iteration);
} catch(std::exception& ex) {
cerr << "Exception: " << ex.what() << endl;
}

@ -15,7 +15,7 @@ constexpr const char *OUTPUT_FILENAME = "nanovg-demo.mkv";
using std::cerr;
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) {
//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;
//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
float hue = (sinf(time * 0.12f) + 1.0f) * 127.5;
if (!v4d->capture())
if (!window->capture())
return false;
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
cvtColor(frameBuffer, rgb, cv::COLOR_BGRA2RGB);
});
@ -153,20 +153,20 @@ static bool iteration() {
cv::cvtColor(hsv, rgb, cv::COLOR_HSV2RGB_FULL);
//Color-conversion from RGB to BGRA. (OpenCL)
v4d->fb([&](cv::UMat &frameBuffer) {
window->fb([&](cv::UMat &frameBuffer) {
cv::cvtColor(rgb, frameBuffer, cv::COLOR_RGB2BGRA);
});
//Render using nanovg
v4d->nvg([&](const cv::Size &sz) {
window->nvg([&](const cv::Size &sz) {
hue = ((170 + uint8_t(255 - hue))) % 255;
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.
return v4d->display();
return window->display();
}
#ifndef __EMSCRIPTEN__
@ -179,20 +179,20 @@ int main(int argc, char **argv) {
int main() {
#endif
using namespace cv::v4d;
v4d = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "NanoVG Demo", OFFSCREEN);
v4d->printSystemInfo();
window = V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "NanoVG Demo", OFFSCREEN);
window->printSystemInfo();
#ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'), src.fps(), cv::Size(WIDTH, HEIGHT));
v4d->setSource(src);
v4d->setSink(sink);
window->setSource(src);
window->setSink(sink);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
v4d->setSource(src);
Source src = makeCaptureSource(WIDTH, HEIGHT, window);
window->setSource(src);
#endif
v4d->run(iteration);
window->run(iteration);
return 0;
}

@ -5,6 +5,12 @@
#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 <vector>
#include <set>
@ -12,12 +18,6 @@
#include <thread>
#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::endl;
using std::vector;
@ -47,9 +47,9 @@ constexpr const char* OUTPUT_FILENAME = "optflow-demo.mkv";
#endif
constexpr bool OFFSCREEN = false;
cv::Ptr<cv::v4d::V4D> v4d;
cv::Ptr<cv::v4d::V4D> window;
#ifndef __EMSCRIPTEN__
cv::Ptr<cv::v4d::V4D> v4d2;
cv::Ptr<cv::v4d::V4D> menuWindow;
#endif
/** Visualization parameters **/
@ -306,8 +306,8 @@ static void composite_layers(cv::UMat& background, const cv::UMat& foreground, c
cv::add(background, post, dst);
}
static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain, cv::Ptr<cv::v4d::V4D> v4dMenu) {
v4dMain->nanogui([&](cv::v4d::FormHelper& form){
static void setup_gui(cv::Ptr<cv::v4d::V4D> main, cv::Ptr<cv::v4d::V4D> menu) {
main->nanogui([&](cv::v4d::FormHelper& form){
form.makeDialog(5, 30, "Effects");
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");
});
v4dMenu->nanogui([&](cv::v4d::FormHelper& form){
menu->nanogui([&](cv::v4d::FormHelper& form){
form.makeDialog(8, 16, "Display");
form.makeGroup("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) {
v4dMain->setFrameBufferScaling(s);
main->setFrameBufferScaling(s);
});
#ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() {
v4dMain->setFullscreen(!v4dMain->isFullscreen());
main->setFullscreen(!main->isFullscreen());
});
form.makeButton("Offscreen", [=]() {
v4dMain->setVisible(!v4dMain->isVisible());
main->setVisible(!main->isVisible());
});
#endif
});
@ -402,18 +402,18 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain, cv::Ptr<cv::v4d::V4D> v4dMe
static bool iteration() {
//BGRA
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
static cv::UMat menuFrame;
//GREY
static cv::UMat downPrevGrey, downNextGrey, downMotionMaskGrey;
static vector<cv::Point2f> detectedPoints;
if(!v4d->capture())
if(!window->capture())
return false;
v4d->fb([&](cv::UMat& frameBuffer) {
cv::resize(frameBuffer, down, cv::Size(v4d->framebufferSize().width * fg_scale, v4d->framebufferSize().height * fg_scale));
window->fb([&](cv::UMat& frameBuffer) {
cv::resize(frameBuffer, down, cv::Size(window->framebufferSize().width * fg_scale, window->framebufferSize().height * fg_scale));
frameBuffer.copyTo(background);
});
@ -423,7 +423,7 @@ static bool iteration() {
//Detect trackable points in the motion mask
detect_points(downMotionMaskGrey, detectedPoints);
v4d->nvg([&]() {
window->nvg([&]() {
cv::v4d::nvg::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.
@ -437,7 +437,7 @@ static bool iteration() {
downPrevGrey = downNextGrey.clone();
v4d->fb([&](cv::UMat& frameBuffer){
window->fb([&](cv::UMat& frameBuffer){
cv::resize(foreground, foreground, frameBuffer.size());
//Put it all together (OpenCL)
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__
v4d->write();
window->write();
v4d2->feed(menuFrame);
menuWindow->feed(menuFrame);
if(!v4d2->display())
if(!menuWindow->display())
return false;
#endif
//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__
int main(int argc, char **argv) {
@ -469,35 +469,35 @@ int main() {
#endif
try {
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__
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
v4d->printSystemInfo();
window->printSystemInfo();
if (!OFFSCREEN) {
#ifndef __EMSCRIPTEN__
setup_gui(v4d, v4d2);
v4d2->setResizable(false);
setup_gui(window, menuWindow);
menuWindow->setResizable(false);
#else
setup_gui(v4d, v4d);
setup_gui(window, window);
#endif
}
#ifndef __EMSCRIPTEN__
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));
v4d->setSink(sink);
window->setSink(sink);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
v4d->setSource(src);
Source src = makeCaptureSource(WIDTH, HEIGHT, window);
window->setSource(src);
#endif
v4d->run(iteration);
window->run(iteration);
} catch (std::exception& ex) {
cerr << ex.what() << endl;
}

@ -14,8 +14,8 @@ constexpr unsigned int HEIGHT = 720;
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
constexpr unsigned int DOWNSIZE_WIDTH = 640;
constexpr unsigned int DOWNSIZE_HEIGHT = 360;
constexpr double WIDTH_FACTOR = double(WIDTH) / DOWNSIZE_WIDTH;
constexpr double HEIGHT_FACTOR = double(HEIGHT) / DOWNSIZE_HEIGHT;
constexpr double WIDTH_SCALE = double(WIDTH) / DOWNSIZE_WIDTH;
constexpr double HEIGHT_SCALE = double(HEIGHT) / DOWNSIZE_HEIGHT;
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr const char* OUTPUT_FILENAME = "pedestrian-demo.mkv";
@ -29,7 +29,7 @@ using std::endl;
using std::vector;
using std::string;
cv::Ptr<cv::v4d::V4D> v4d;
cv::Ptr<cv::v4d::V4D> window;
cv::HOGDescriptor hog;
//adapted from cv::dnn_objdetect::InferBbox
@ -128,10 +128,10 @@ static bool iteration() {
static bool redetect = true;
if(!v4d->capture())
if(!window->capture())
return false;
v4d->fb([&](cv::UMat& frameBuffer){
window->fb([&](cv::UMat& frameBuffer){
cvtColor(frameBuffer,videoFrame,cv::COLOR_BGRA2RGB);
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;
clear();
beginPath();
strokeWidth(std::fmax(2.0, sz.width / 960.0));
strokeColor(cv::v4d::colorConvert(cv::Scalar(0, 127, 255, 200), cv::COLOR_HLS2BGR));
float width = tracked.width * WIDTH_FACTOR;
float height = tracked.height * HEIGHT_FACTOR;
float cx = tracked.x * WIDTH_FACTOR + (width / 2.0f);
float cy = tracked.y * HEIGHT_FACTOR + (height / 2.0f);
float width = tracked.width * WIDTH_SCALE;
float height = tracked.height * HEIGHT_SCALE;
float cx = tracked.x * WIDTH_SCALE + (width / 2.0f);
float cy = tracked.y * HEIGHT_SCALE + (height / 2.0f);
ellipse(cx, cy, width / 2.0f, height / 2.0f);
stroke();
});
v4d->fb([&](cv::UMat& frameBuffer){
window->fb([&](cv::UMat& frameBuffer){
//Put it all together
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.
return v4d->display();
return window->display();
}
#ifndef __EMSCRIPTEN__
@ -211,24 +211,24 @@ int main(int argc, char **argv) {
int main() {
#endif
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());
v4d->printSystemInfo();
window->printSystemInfo();
#ifndef __EMSCRIPTEN__
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));
v4d->setSink(sink);
window->setSink(sink);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
v4d->setSource(src);
Source src = makeCaptureSource(WIDTH, HEIGHT, window);
window->setSource(src);
#endif
v4d->run(iteration);
window->run(iteration);
return 0;
}

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

@ -18,7 +18,7 @@ constexpr double FPS = 60;
constexpr const char* OUTPUT_FILENAME = "shader-demo.mkv";
#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);
@ -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]);
} else {
gl_FragDepth = -1.0;
outColor = vec4(0,0,0,0);
}
}
@ -192,8 +193,6 @@ static void init_scene(const cv::Size& sz) {
}
static void render_scene() {
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
if (zoom >= 1) {
zoom_incr = -0.01;
iterations = 0;
@ -313,27 +312,27 @@ static void setup_gui(cv::Ptr<cv::v4d::V4D> v4dMain) {
}
static bool iteration() {
if(!v4d->capture())
if(!window->capture())
return false;
//Render using OpenGL
v4d->gl(render_scene);
window->gl(render_scene);
//To slow for WASM but works
#ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL
v4d->fb([](cv::UMat& frameBuffer) {
window->fb([](cv::UMat& frameBuffer) {
//Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, glow_kernel_size);
});
#endif
#ifndef __EMSCRIPTEN__
v4d->write();
window->write();
#endif
++iterations;
//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__
@ -347,28 +346,28 @@ int main() {
#endif
try {
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) {
setup_gui(v4d);
setup_gui(window);
}
v4d->printSystemInfo();
window->printSystemInfo();
v4d->gl(init_scene);
window->gl(init_scene);
#ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]);
v4d->setSource(src);
window->setSource(src);
Sink sink = makeWriterSink(OUTPUT_FILENAME, cv::VideoWriter::fourcc('V', 'P', '9', '0'),
FPS, cv::Size(WIDTH, HEIGHT));
v4d->setSink(sink);
window->setSink(sink);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
v4d->setSource(src);
Source src = makeCaptureSource(WIDTH, HEIGHT, window);
window->setSource(src);
#endif
v4d->run(iteration);
window->run(iteration);
} catch (std::exception& ex) {
cerr << "Exception: " << ex.what() << endl;
}

@ -6,18 +6,19 @@ using namespace cv::v4d;
int main() {
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([=]() {
//Creates a NanoVG context and draws eyes
window->nvg([](const Size& sz) {
//Calls from this namespace may only be used inside a nvg context
using namespace cv::v4d::nvg;
clear();
float t = cv::getTickCount();
float t = cv::getTickCount() / cv::getTickFrequency();
float x = 0;
float y = 0;
float w = sz.width / 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 my = h / 2.0;
Paint gloss, bg;

@ -7,18 +7,20 @@ using namespace cv::v4d;
int main() {
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([=]() {
//Creates a NanoVG context and draws eyes
window->nvg([](const Size& sz) {
//Calls from this namespace may only be used inside a nvg context
using namespace cv::v4d::nvg;
clear();
float t = cv::getTickCount();
float t = cv::getTickCount() / cv::getTickFrequency();
float x = 0;
float y = 0;
float w = sz.width / 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 my = h / 2.0;
Paint gloss, bg;
@ -91,7 +93,6 @@ int main() {
});
window->fb([](UMat& framebuffer) {
// cerr << "COUNT1:" << cv::v4d::detail::cnz(framebuffer) << endl;
//Heavily blurs the eyes using a cheap boxFilter
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 uniform_transform;
cv::Ptr<cv::v4d::V4D> v4d;
cv::Ptr<cv::v4d::V4D> window;
static GLuint load_shader() {
#ifndef OPENCV_V4D_USE_ES3
@ -134,8 +134,6 @@ static void init_scene() {
}
static void render_scene() {
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
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() {
using namespace cv::v4d;
if(!v4d->capture())
if(!window->capture())
return false;
//Render using OpenGL
v4d->gl(render_scene);
window->gl(render_scene);
//to slow for wasm
#ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL
v4d->fb([&](cv::UMat& frameBuffer) {
window->fb([&](cv::UMat& frameBuffer) {
//Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE);
});
#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.
return v4d->display();
return window->display();
}
#ifndef __EMSCRIPTEN__
@ -219,24 +217,24 @@ int main(int argc, char** argv) {
int main() {
#endif
using namespace cv::v4d;
v4d = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Video Demo", OFFSCREEN);
v4d->printSystemInfo();
window = cv::v4d::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(), "Video Demo", OFFSCREEN);
window->printSystemInfo();
#ifndef __EMSCRIPTEN__
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));
v4d->setSink(sink);
window->setSink(sink);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT, v4d);
v4d->setSource(src);
Source src = makeCaptureSource(WIDTH, HEIGHT, window);
window->setSource(src);
#endif
v4d->gl(init_scene);
v4d->run(iteration);
window->gl(init_scene);
window->run(iteration);
return 0;
}

@ -28,6 +28,13 @@ void GLContext::render(std::function<void(const cv::Size&)> fn) {
{
FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER);
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());
}
if(!fbCtx().isShared()) {

@ -26,6 +26,13 @@ void NanoguiContext::render() {
{
FrameBufferContext::GLScope glScope(fbCtx(), GL_FRAMEBUFFER);
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();
}
{
@ -62,9 +69,6 @@ void NanoguiContext::updateFps(bool print, bool graphical) {
NanoVGContext::render([this](const Size sz){
CV_UNUSED(sz);
using namespace cv::v4d::nvg;
#ifdef __EMSCRIPTEN__
clear({0.0,0.0,0.0,0.0});
#endif
string txt = "FPS: " + std::to_string(fps_);
beginPath();
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);
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);
cv::v4d::nvg::detail::NVG::initializeContext(context_);
fn(fbCtx().size());

Loading…
Cancel
Save