fixed a ton of warnings

pull/3471/head
kallaballa 2 years ago
parent 991543a394
commit 09fef18a07
  1. 17
      modules/v4d/CMakeLists.txt
  2. 15
      modules/v4d/include/opencv2/v4d/v4d.hpp
  3. 33
      modules/v4d/samples/beauty-demo.cpp
  4. 22
      modules/v4d/samples/cube-demo.cpp
  5. 9
      modules/v4d/samples/custom_source_and_sink.cpp
  6. 1
      modules/v4d/samples/display_image.cpp
  7. 25
      modules/v4d/samples/font-demo.cpp
  8. 2
      modules/v4d/samples/font_rendering.cpp
  9. 2
      modules/v4d/samples/font_with_gui.cpp
  10. 12
      modules/v4d/samples/nanovg-demo.cpp
  11. 37
      modules/v4d/samples/optflow-demo.cpp
  12. 20
      modules/v4d/samples/pedestrian-demo.cpp
  13. 4
      modules/v4d/samples/render_opengl.cpp
  14. 275
      modules/v4d/samples/shader-demo.cpp
  15. 2
      modules/v4d/samples/vector_graphics.cpp
  16. 2
      modules/v4d/samples/vector_graphics_and_fb.cpp
  17. 328
      modules/v4d/samples/video-demo.cpp
  18. 4
      modules/v4d/samples/video_editing.cpp
  19. 14
      modules/v4d/src/detail/framebuffercontext.cpp
  20. 17
      modules/v4d/src/util.cpp
  21. 32
      modules/v4d/src/v4d.cpp

@ -11,12 +11,10 @@ macro(add_emscripten_sample sample source)
ocv_target_include_modules(${sample} opencv_core opencv_imgproc opencv_videoio opencv_video opencv_imgcodecs opencv_v4d opencv_face opencv_tracking opencv_objdetect opencv_stitching opencv_optflow opencv_imgcodecs opencv_features2d opencv_dnn opencv_flann)
ocv_target_link_libraries(${sample} LINK_PRIVATE opencv_core opencv_imgproc opencv_videoio opencv_video opencv_imgcodecs
opencv_v4d opencv_face opencv_tracking opencv_objdetect opencv_stitching opencv_optflow opencv_imgcodecs opencv_features2d opencv_dnn opencv_flann nanogui ${GLEW_LIBRARIES})
target_link_directories(${sample} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../lib")
target_link_directories(${sample} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../../lib")
target_compile_features(${sample} PRIVATE cxx_std_20)
set_target_properties(${sample} PROPERTIES SUFFIX ".js")
# configure_file("${CMAKE_CURRENT_LIST_DIR}/samples/${sample}.html" "${CMAKE_CURRENT_BINARY_DIR}/../../bin/${sample}.html" COPYONLY)
add_custom_command(
add_custom_command(
TARGET ${sample} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${CMAKE_CURRENT_LIST_DIR}/samples/${sample}.html"
@ -29,9 +27,9 @@ macro(add_binary_sample sample)
endmacro()
if(EMSCRIPTEN)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -sINITIAL_MEMORY=512MB -sTOTAL_MEMORY=512MB -sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -sINITIAL_MEMORY=512MB -sTOTAL_MEMORY=512MB -sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -sINITIAL_MEMORY=512MB -sTOTAL_MEMORY=512MB -sALLOW_MEMORY_GROWTH=1 -sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -sINITIAL_MEMORY=512MB -sTOTAL_MEMORY=512MB -sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -sINITIAL_MEMORY=512MB -sTOTAL_MEMORY=512MB -sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_LD_FLAGS} -sINITIAL_MEMORY=512MB -sTOTAL_MEMORY=512MB -sUSE_GLFW=3 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2")
else()
if(NOT GLEW_FOUND)
message(STATUS "Module opencv_v4d disabled because GLEW was not found")
@ -45,7 +43,6 @@ if (${idx} LESS 0)
message(STATUS "Module opencv_v4d disabled because it requires C++20")
ocv_module_disable(v4d)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L../../lib/")
OCV_OPTION(OPENCV_V4D_ENABLE_ES3 "Enable OpenGL ES 3.0 backend for V4D" OFF
VERIFY HAVE_OPENGL)
@ -144,11 +141,11 @@ target_compile_features(opencv_v4d PRIVATE cxx_std_20)
target_compile_features(nanogui PRIVATE cxx_std_20)
target_compile_features(nanovg PRIVATE cxx_std_20)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-parameter -Wdeprecated-enum-enum-conversion -Wformat-truncation)
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-enum-enum-conversion)
target_link_directories(${the_module} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../lib")
if(EMSCRIPTEN)
ocv_target_link_libraries(${the_module} -lnanogui)
else()
ocv_target_link_libraries(${the_module} -lOpenCL -lnanogui -lnanovg OpenGL::OpenGL GLEW::glew)
ocv_target_link_libraries(${the_module} -lOpenCL -lnanogui OpenGL::OpenGL GLEW::glew)
endif()

@ -91,16 +91,7 @@ template<typename T> void find_widgets(nanogui::Widget* parent, std::vector<T>&
* @param line The file line of the error.
* @param expression The expression that failed.
*/
static 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 gl_check_error(const std::filesystem::path& file, unsigned int line, const char* expression);
/*!
* Convenience macro to check for OpenGL errors.
*/
@ -197,6 +188,8 @@ public:
* @param fn A function object that is passed the size of the framebuffer
*/
CV_EXPORTS void gl(std::function<void(const cv::Size&)> fn);
CV_EXPORTS void gl(std::function<void()> fn);
/*!
* Execute function object fn inside a framebuffer context.
* The context acquires the framebuffer from OpenGL (either by up-/download or by cl-gl sharing)
@ -213,6 +206,8 @@ public:
* and performs drawing using cv::viz::nvg
*/
CV_EXPORTS void nvg(std::function<void(const cv::Size&)> fn);
CV_EXPORTS void nvg(std::function<void()> fn);
/*!
* Execute function object fn inside a nanogui context.
* The context provides a #cv::viz::FormHelper instance to the function object

@ -29,7 +29,9 @@ constexpr unsigned int WIDTH = 1920;
constexpr unsigned int HEIGHT = 1080;
constexpr double SCALE = 0.125; //Scale at which face detection is performed
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr const char *OUTPUT_FILENAME = "beauty-demo.mkv";
#endif
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
/** Effect parameters **/
@ -137,7 +139,7 @@ struct FaceFeatures {
};
//based on the detected FaceFeatures guesses a decent face oval and draws a mask.
void draw_face_oval_mask(const vector<FaceFeatures> &lm) {
static void draw_face_oval_mask(const vector<FaceFeatures> &lm) {
using namespace cv::viz::nvg;
for (size_t i = 0; i < lm.size(); i++) {
vector<vector<cv::Point2f>> features = lm[i].features();
@ -152,7 +154,7 @@ void draw_face_oval_mask(const vector<FaceFeatures> &lm) {
}
//Draws a mask consisting of eyes and lips areas (deduced from FaceFeatures)
void draw_face_eyes_and_lips_mask(const vector<FaceFeatures> &lm) {
static void draw_face_eyes_and_lips_mask(const vector<FaceFeatures> &lm) {
using namespace cv::viz::nvg;
for (size_t i = 0; i < lm.size(); i++) {
vector<vector<cv::Point2f>> features = lm[i].features();
@ -179,7 +181,7 @@ void draw_face_eyes_and_lips_mask(const vector<FaceFeatures> &lm) {
}
//adjusts the saturation of a UMat
void adjust_saturation(const cv::UMat &srcBGR, cv::UMat &dstBGR, float factor) {
static void adjust_saturation(const cv::UMat &srcBGR, cv::UMat &dstBGR, float factor) {
static vector<cv::UMat> channels;
static cv::UMat hls;
@ -191,8 +193,8 @@ void adjust_saturation(const cv::UMat &srcBGR, cv::UMat &dstBGR, float factor) {
}
//Setup the gui
void setup_gui(cv::Ptr<cv::viz::V4D> v4d) {
v4d->nanogui([&](cv::viz::FormHelper& form){
static void setup_gui(cv::Ptr<cv::viz::V4D> v) {
v->nanogui([&](cv::viz::FormHelper& form){
form.makeDialog(5, 30, "Effect");
form.makeGroup("Display");
@ -200,11 +202,11 @@ void setup_gui(cv::Ptr<cv::viz::V4D> v4d) {
form.makeFormVariable("Stretch", stretch, "Enable or disable stetching to the window size");
#ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() {
v4d->setFullscreen(!v4d->isFullscreen());
v->setFullscreen(!v->isFullscreen());
});
#endif
form.makeButton("Offscreen", [=]() {
v4d->setOffscreen(!v4d->isOffscreen());
v->setOffscreen(!v->isOffscreen());
});
form.makeGroup("Face Skin");
@ -231,7 +233,7 @@ void setup_gui(cv::Ptr<cv::viz::V4D> v4d) {
});
}
bool iteration() {
static bool iteration() {
try {
#ifdef USE_TRACKER
static bool trackerInitalized = false;
@ -305,8 +307,8 @@ bool iteration() {
featuresList.push_back(FaceFeatures(faceRects[i], shapes[i], float(down.size().width) / WIDTH));
}
v4d->nvg([&](const cv::Size &sz) {
v4d->clear();
v4d->clear();
v4d->nvg([&]() {
//Draw the face oval of the first face
draw_face_oval_mask(featuresList);
});
@ -316,8 +318,8 @@ bool iteration() {
cvtColor(frameBuffer, faceOval, cv::COLOR_BGRA2GRAY);
});
v4d->nvg([&](const cv::Size &sz) {
v4d->clear();
v4d->clear();
v4d->nvg([&]() {
//Draw eyes eyes and lips areas of the first face
draw_face_eyes_and_lips_mask(featuresList);
});
@ -392,14 +394,17 @@ bool iteration() {
return true;
}
int main(int argc, char **argv) {
using namespace cv::viz;
#ifndef __EMSCRIPTEN__
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: beauty-demo <input-video-file>" << endl;
exit(1);
}
#else
int main() {
#endif
using namespace cv::viz;
facemark->loadModel("lbfmodel.yaml");
v4d->setStretching(stretch);

@ -11,9 +11,11 @@
constexpr long unsigned int WIDTH = 1920;
constexpr long unsigned int HEIGHT = 1080;
constexpr double FPS = 60;
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr double FPS = 60;
constexpr const char* OUTPUT_FILENAME = "cube-demo.mkv";
#endif
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
const int GLOW_KERNEL_SIZE = std::max(int(DIAG / 138 % 2 == 0 ? DIAG / 138 + 1 : DIAG / 138), 1);
@ -28,10 +30,10 @@ unsigned int shader_program;
unsigned int vao;
unsigned int uniform_transform;
cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT),
static cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT),
OFFSCREEN, "Cube Demo");
GLuint load_shader() {
static GLuint load_shader() {
#ifndef OPENCV_V4D_USE_ES3
const string shaderVersion = "330";
#else
@ -70,7 +72,7 @@ GLuint load_shader() {
return cv::viz::init_shader(vert.c_str(), frag.c_str(), "fragColor");
}
void init_scene(const cv::Size& sz) {
static void init_scene() {
glEnable (GL_DEPTH_TEST);
float vertices[] = {
@ -137,7 +139,7 @@ void init_scene(const cv::Size& sz) {
uniform_transform = glGetUniformLocation(shader_program, "transform");
}
void render_scene(const cv::Size& sz) {
static void render_scene() {
glClearColor(0.1, 0.12, 0.2, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -165,7 +167,8 @@ void render_scene(const cv::Size& sz) {
}
void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
#ifndef __EMSCRIPTEN__
static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
static cv::UMat resize;
static cv::UMat blur;
static cv::UMat dst16;
@ -187,8 +190,9 @@ void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
cv::bitwise_not(dst, dst);
}
#endif
bool iteration() {
static bool iteration() {
using namespace cv::viz;
//Render using OpenGL
@ -214,7 +218,11 @@ bool iteration() {
return true;
}
#ifndef __EMSCRIPTEN__
int main(int argc, char** argv) {
#else
int main() {
#endif
using namespace cv::viz;
if (!v4d->isOffscreen())

@ -3,7 +3,7 @@
# include <opencv2/imgcodecs.hpp>
#endif
int main(int argc, char** argv) {
int main() {
using namespace cv;
using namespace cv::viz;
@ -31,6 +31,8 @@ int main(int argc, char** argv) {
try {
#ifndef __EMSCRIPTEN__
imwrite(std::to_string(cnt) + ".png", frame);
#else
CV_UNUSED(frame);
#endif
} catch(std::exception& ex) {
cerr << "Unable to write frame: " << ex.what() << endl;
@ -38,10 +40,11 @@ int main(int argc, char** argv) {
}
++cnt;
if(cnt > std::numeric_limits<long>().max() / 2.0)
if(cnt > std::numeric_limits<long>().max() / 2.0) {
cnt = 0;
}
return true;
return true;
});
//Attach source and sink

@ -19,4 +19,3 @@ int main() {
//terminates or the functor returns false.
v4d->run([=](){ return v4d->display(); });
}

@ -18,10 +18,11 @@
/** Application parameters **/
constexpr unsigned int WIDTH = 1920;
constexpr unsigned int HEIGHT = 1080;
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr const char* OUTPUT_FILENAME = "font-demo.mkv";
constexpr double FPS = 60;
#endif
const cv::Scalar_<float> INITIAL_COLOR = cv::viz::colorConvert(cv::Scalar(0.15 * 180.0, 128, 255, 255), cv::COLOR_HLS2BGR);
/** Visualization parameters **/
@ -44,13 +45,13 @@ using std::string;
using std::vector;
using std::istringstream;
cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Font Demo");
static cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Font Demo");
vector<string> lines;
bool update_stars = true;
bool update_perspective = true;
static bool update_stars = true;
static bool update_perspective = true;
void setup_gui(cv::Ptr<cv::viz::V4D> v4d) {
v4d->nanogui([&](cv::viz::FormHelper& form){
static void setup_gui(cv::Ptr<cv::viz::V4D> v4dMain) {
v4dMain->nanogui([&](cv::viz::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");
@ -95,16 +96,16 @@ void setup_gui(cv::Ptr<cv::viz::V4D> v4d) {
form.makeFormVariable("Show FPS", show_fps, "Enable or disable the On-screen FPS display");
#ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() {
v4d->setFullscreen(!v4d->isFullscreen());
v4dMain->setFullscreen(!v4dMain->isFullscreen());
});
#endif
form.makeButton("Offscreen", [=]() {
v4d->setOffscreen(!v4d->isOffscreen());
v4dMain->setOffscreen(!v4dMain->isOffscreen());
});
});
}
bool iteration() {
static bool iteration() {
//BGRA
static cv::UMat stars, warped;
//transformation matrix
@ -132,7 +133,7 @@ bool iteration() {
const auto& size = rng.uniform(min_star_size, max_star_size);
strokeWidth(size);
strokeColor(cv::Scalar(255, 255, 255, star_alpha * 255.0f));
circle(rng.uniform(0, WIDTH) , rng.uniform(0, HEIGHT), size / 2.0);
circle(rng.uniform(0, sz.width) , rng.uniform(0, sz.height), size / 2.0);
stroke();
}
});
@ -168,7 +169,7 @@ bool iteration() {
for (size_t i = 0; i < lines.size(); ++i) {
y = (i * font_size);
if (y + translateY < textHeight && y + translateY + font_size > 0) {
text(WIDTH / 2.0, y, lines[i].c_str(), lines[i].c_str() + lines[i].size());
text(sz.width / 2.0, y, lines[i].c_str(), lines[i].c_str() + lines[i].size());
}
}
});
@ -203,7 +204,7 @@ bool iteration() {
return true;
}
int main(int argc, char **argv) {
int main() {
try {
using namespace cv::viz;

@ -1,6 +1,6 @@
#include <opencv2/v4d/v4d.hpp>
int main(int argc, char** argv) {
int main() {
using namespace cv;
using namespace cv::viz;

@ -1,6 +1,6 @@
#include <opencv2/v4d/v4d.hpp>
int main(int argc, char** argv) {
int main() {
using namespace cv;
using namespace cv::viz;

@ -8,14 +8,16 @@
constexpr unsigned int WIDTH = 1920;
constexpr unsigned int HEIGHT = 1080;
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr const char *OUTPUT_FILENAME = "nanovg-demo.mkv";
#endif
using std::cerr;
using std::endl;
static cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "NanoVG Demo");
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
using namespace cv::viz::nvg;
int i;
@ -117,7 +119,7 @@ void draw_color_wheel(float x, float y, float w, float h, float hue) {
restore();
}
bool iteration() {
static bool iteration() {
static std::vector<cv::UMat> hsvChannels;
static cv::UMat rgb;
static cv::UMat bgra;
@ -170,12 +172,16 @@ bool iteration() {
return true;
}
#ifndef __EMSCRIPTEN__
int main(int argc, char **argv) {
using namespace cv::viz;
if (argc != 2) {
cerr << "Usage: nanovg-demo <video-file>" << endl;
exit(1);
}
#else
int main() {
#endif
using namespace cv::viz;
if (!v4d->isOffscreen())
v4d->setVisible(true);

@ -42,7 +42,9 @@ enum PostProcModes {
constexpr unsigned int WIDTH = 1920;
constexpr unsigned int HEIGHT = 1080;
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
#ifndef __EMSCRIPTEN__
constexpr const char* OUTPUT_FILENAME = "optflow-demo.mkv";
#endif
constexpr bool OFFSCREEN = false;
static cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Sparse Optical Flow Demo");
@ -118,7 +120,7 @@ int bloom_thresh = 210;
//The intensity of the bloom filter
float bloom_gain = 3;
void prepare_motion_mask(const cv::UMat& srcGrey, cv::UMat& motionMaskGrey) {
static void prepare_motion_mask(const cv::UMat& srcGrey, cv::UMat& motionMaskGrey) {
static cv::Ptr<cv::BackgroundSubtractor> bg_subtrator = cv::createBackgroundSubtractorMOG2(100, 16.0, false);
static int morph_size = 1;
static cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * morph_size + 1, 2 * morph_size + 1), cv::Point(morph_size, morph_size));
@ -127,7 +129,7 @@ void prepare_motion_mask(const cv::UMat& srcGrey, cv::UMat& motionMaskGrey) {
cv::morphologyEx(motionMaskGrey, motionMaskGrey, cv::MORPH_OPEN, element, cv::Point(element.cols >> 1, element.rows >> 1), 2, cv::BORDER_CONSTANT, cv::morphologyDefaultBorderValue());
}
void detect_points(const cv::UMat& srcMotionMaskGrey, vector<cv::Point2f>& points) {
static void detect_points(const cv::UMat& srcMotionMaskGrey, vector<cv::Point2f>& points) {
static cv::Ptr<cv::FastFeatureDetector> detector = cv::FastFeatureDetector::create(1, false);
static vector<cv::KeyPoint> tmpKeyPoints;
@ -140,7 +142,7 @@ void detect_points(const cv::UMat& srcMotionMaskGrey, vector<cv::Point2f>& point
}
}
bool detect_scene_change(const cv::UMat& srcMotionMaskGrey, const float thresh, const float theshDiff) {
static bool detect_scene_change(const cv::UMat& srcMotionMaskGrey, const float thresh, const float theshDiff) {
static float last_movement = 0;
float movement = cv::countNonZero(srcMotionMaskGrey) / float(srcMotionMaskGrey.cols * srcMotionMaskGrey.rows);
@ -154,7 +156,7 @@ bool detect_scene_change(const cv::UMat& srcMotionMaskGrey, const float thresh,
return result;
}
void visualize_sparse_optical_flow(const cv::UMat &prevGrey, const cv::UMat &nextGrey, const vector<cv::Point2f> &detectedPoints, const float scaleFactor, const int maxStrokeSize, const cv::Scalar color, const int maxPoints, const float pointLossPercent) {
static void visualize_sparse_optical_flow(const cv::UMat &prevGrey, const cv::UMat &nextGrey, const 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;
static std::vector<uchar> status;
@ -213,7 +215,7 @@ void visualize_sparse_optical_flow(const cv::UMat &prevGrey, const cv::UMat &nex
}
}
void bloom(const cv::UMat& src, cv::UMat &dst, int ksize = 3, int threshValue = 235, float gain = 4) {
static void bloom(const cv::UMat& src, cv::UMat &dst, int ksize = 3, int threshValue = 235, float gain = 4) {
static cv::UMat bgr;
static cv::UMat hls;
static cv::UMat ls16;
@ -236,7 +238,7 @@ void bloom(const cv::UMat& src, cv::UMat &dst, int ksize = 3, int threshValue =
addWeighted(src, 1.0, blur, gain, 0, dst);
}
void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
static void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
static cv::UMat resize;
static cv::UMat blur;
static cv::UMat dst16;
@ -258,7 +260,7 @@ void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
cv::bitwise_not(dst, dst);
}
void composite_layers(cv::UMat& background, const cv::UMat& foreground, const cv::UMat& frameBuffer, cv::UMat& dst, int kernelSize, float fgLossPercent, BackgroundModes bgMode, PostProcModes ppMode) {
static void composite_layers(cv::UMat& background, const cv::UMat& foreground, const cv::UMat& frameBuffer, cv::UMat& dst, int kernelSize, float fgLossPercent, BackgroundModes bgMode, PostProcModes ppMode) {
static cv::UMat tmp;
static cv::UMat post;
static cv::UMat backgroundGrey;
@ -304,8 +306,8 @@ void composite_layers(cv::UMat& background, const cv::UMat& foreground, const cv
cv::add(background, post, dst);
}
void setup_gui(cv::Ptr<cv::viz::V4D> v4d, cv::Ptr<cv::viz::V4D> v4dMenu) {
v4d->nanogui([&](cv::viz::FormHelper& form){
static void setup_gui(cv::Ptr<cv::viz::V4D> v4dMain, cv::Ptr<cv::viz::V4D> v4dMenu) {
v4dMain->nanogui([&](cv::viz::FormHelper& form){
form.makeDialog(5, 30, "Effects");
form.makeGroup("Foreground");
@ -382,22 +384,22 @@ void setup_gui(cv::Ptr<cv::viz::V4D> v4d, cv::Ptr<cv::viz::V4D> v4dMenu) {
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) {
v4d->setStretching(s);
v4dMain->setStretching(s);
});
#ifndef __EMSCRIPTEN__
form.makeButton("Fullscreen", [=]() {
v4d->setFullscreen(!v4d->isFullscreen());
v4dMain->setFullscreen(!v4dMain->isFullscreen());
});
form.makeButton("Offscreen", [=]() {
v4d->setOffscreen(!v4d->isOffscreen());
v4dMain->setOffscreen(!v4dMain->isOffscreen());
});
#endif
});
}
bool iteration() {
static bool iteration() {
//BGRA
static cv::UMat background, down;
static cv::UMat foreground(v4d->getFrameBufferSize(), CV_8UC4, cv::Scalar::all(0));
@ -421,7 +423,7 @@ bool iteration() {
//Detect trackable points in the motion mask
detect_points(downMotionMaskGrey, detectedPoints);
v4d->nvg([=](const cv::Size& sz) {
v4d->nvg([=]() {
v4d->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.
@ -462,14 +464,17 @@ bool iteration() {
return true;
}
int main(int argc, char **argv) {
using namespace cv::viz;
#ifndef __EMSCRIPTEN__
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: optflow <input-video-file>" << endl;
exit(1);
}
#else
int main() {
#endif
using namespace cv::viz;
if(!v4d->isOffscreen()) {
v4d->setVisible(true);
#ifndef __EMSCRIPTEN__

@ -19,7 +19,9 @@ constexpr unsigned int DOWNSIZE_HEIGHT = 360;
constexpr double WIDTH_FACTOR = double(WIDTH) / DOWNSIZE_WIDTH;
constexpr double HEIGHT_FACTOR = double(HEIGHT) / DOWNSIZE_HEIGHT;
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr const char* OUTPUT_FILENAME = "pedestrian-demo.mkv";
#endif
// Intensity of blur defined by kernel size. The default scales with the image diagonal.
const int BLUR_KERNEL_SIZE = std::max(int(DIAG / 200 % 2 == 0 ? DIAG / 200 + 1 : DIAG / 200), 1);
@ -38,7 +40,7 @@ static inline bool pair_comparator(std::pair<double, size_t> l1, std::pair<doubl
}
//adapted from cv::dnn_objdetect::InferBbox
void intersection_over_union(std::vector<std::vector<double> > *boxes, std::vector<double> *base_box, std::vector<double> *iou) {
static void intersection_over_union(std::vector<std::vector<double> > *boxes, std::vector<double> *base_box, std::vector<double> *iou) {
double g_xmin = (*base_box)[0];
double g_ymin = (*base_box)[1];
double g_xmax = (*base_box)[2];
@ -65,7 +67,7 @@ void intersection_over_union(std::vector<std::vector<double> > *boxes, std::vect
}
//adapted from cv::dnn_objdetect::InferBbox
std::vector<bool> non_maximal_suppression(std::vector<std::vector<double> > *boxes, std::vector<double> *probs, const double threshold = 0.1) {
static std::vector<bool> non_maximal_suppression(std::vector<std::vector<double> > *boxes, std::vector<double> *probs, const double threshold = 0.1) {
std::vector<bool> keep(((*probs).size()));
std::fill(keep.begin(), keep.end(), true);
std::vector<size_t> prob_args_sorted((*probs).size());
@ -102,14 +104,14 @@ std::vector<bool> non_maximal_suppression(std::vector<std::vector<double> > *box
return keep;
}
void composite_layers(const cv::UMat background, const cv::UMat frameBuffer, cv::UMat dst, int blurKernelSize) {
static void composite_layers(const cv::UMat background, const cv::UMat frameBuffer, cv::UMat dst, int blurKernelSize) {
static cv::UMat blur;
cv::boxFilter(frameBuffer, blur, -1, cv::Size(blurKernelSize, blurKernelSize), cv::Point(-1,-1), true, cv::BORDER_REPLICATE);
cv::add(background, blur, dst);
}
bool iteration() {
static bool iteration() {
//BGRA
static cv::UMat background;
//RGB
@ -181,7 +183,7 @@ bool iteration() {
v4d->clear();
beginPath();
strokeWidth(std::fmax(2.0, WIDTH / 960.0));
strokeWidth(std::fmax(2.0, sz.width / 960.0));
strokeColor(cv::viz::colorConvert(cv::Scalar(0, 127, 255, 200), cv::COLOR_HLS2BGR));
float width = tracked.width * WIDTH_FACTOR;
float height = tracked.height * HEIGHT_FACTOR;
@ -207,14 +209,16 @@ bool iteration() {
return true;
}
#ifndef __EMSCRIPTEN__
int main(int argc, char **argv) {
using namespace cv::viz;
if (argc != 2) {
std::cerr << "Usage: pedestrian-demo <video-input>" << endl;
exit(1);
}
#else
int main() {
#endif
using namespace cv::viz;
hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());
if (!v4d->isOffscreen())

@ -1,6 +1,6 @@
#include <opencv2/v4d/v4d.hpp>
int main(int argc, char** argv) {
int main() {
using namespace cv;
using namespace cv::viz;
@ -12,7 +12,7 @@ int main(int argc, char** argv) {
});
v4d->run([=]() {
v4d->gl([](const Size& sz) {
v4d->gl([]() {
//Clears the screen blue
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

@ -10,11 +10,16 @@ using std::endl;
constexpr long unsigned int WIDTH = 1920;
constexpr long unsigned int HEIGHT = 1080;
constexpr double FPS = 60;
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr double FPS = 60;
constexpr const char* OUTPUT_FILENAME = "shader-demo.mkv";
#endif
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
static cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT),
cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Shader Demo");
int glow_kernel_size = std::max(int(DIAG / 200 % 2 == 0 ? DIAG / 200 + 1 : DIAG / 200), 1);
/** mandelbrot control parameters **/
@ -51,25 +56,17 @@ GLuint VAO;
GLuint VBO, EBO;
// vertex position, color
float vertices[] =
{
float vertices[] = {
// x y z
-1.0f, -1.0f, -0.0f,
1.0f, 1.0f, -0.0f,
-1.0f, 1.0f, -0.0f,
1.0f, -1.0f, -0.0f
};
unsigned int indices[] =
{
-1.0f, -1.0f, -0.0f, 1.0f, 1.0f, -0.0f, -1.0f, 1.0f, -0.0f, 1.0f, -1.0f, -0.0f };
unsigned int indices[] = {
// 2---,1
// | .' |
// 0'---3
0, 1, 2,
0, 3, 1
};
0, 1, 2, 0, 3, 1 };
void load_buffer_data(){
static void load_buffer_data() {
#ifndef OPENCV_V4D_USE_ES3
glGenVertexArrays(1, &VAO);
@ -85,7 +82,7 @@ void load_buffer_data(){
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@ -95,88 +92,30 @@ void load_buffer_data(){
}
//workaround: required with emscripten + nanogui on every iteration before rendering
void rebind_buffers() {
static void rebind_buffers() {
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
GLuint init_shader(const char* vShader, const char* fShader, const char* outputAttributeName) {
struct Shader {
GLenum type;
const char* source;
} shaders[2] = {
{ GL_VERTEX_SHADER, vShader },
{ GL_FRAGMENT_SHADER, fShader }
};
GLuint program = glCreateProgram();
for ( int i = 0; i < 2; ++i ) {
Shader& s = shaders[i];
GLuint shader = glCreateShader( s.type );
glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
glCompileShader( shader );
GLint compiled;
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled ) {
std::cerr << " failed to compile:" << std::endl;
GLint logSize;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
char* logMsg = new char[logSize];
glGetShaderInfoLog( shader, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
glAttachShader( program, shader );
}
#ifndef OPENCV_V4D_USE_ES3
/* Link output */
glBindFragDataLocation(program, 0, outputAttributeName);
#endif
/* link and error check */
glLinkProgram(program);
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
std::cerr << "Shader program failed to link" << std::endl;
GLint logSize;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog( program, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;
exit( EXIT_FAILURE );
}
/* use program object */
glUseProgram(program);
return program;
}
//mandelbrot shader code adapted from my own project: https://github.com/kallaballa/FractalDive#after
void load_shader(){
static void load_shader() {
#ifndef OPENCV_V4D_USE_ES3
const string shaderVersion = "330";
#else
const string shaderVersion = "300 es";
#endif
const string vert = " #version " + shaderVersion + R"(
const string vert =
" #version " + shaderVersion
+ R"(
in vec4 position;
void main()
@ -184,7 +123,9 @@ void load_shader(){
gl_Position = vec4(position.xyz, 1.0);
})";
const string frag = " #version " + shaderVersion + R"(
const string frag =
" #version " + shaderVersion
+ R"(
precision lowp float;
out vec4 outColor;
@ -247,14 +188,14 @@ void load_shader(){
cerr << "##### Fragment Shader #####" << endl;
cerr << frag << endl;
shader_program_hdl = init_shader(vert.c_str(), frag.c_str(), "fragColor");
shader_program_hdl = cv::viz::init_shader(vert.c_str(), frag.c_str(), "fragColor");
}
float easeInOutQuint(float x) {
static float easeInOutQuint(float x) {
return x < 0.5f ? 16.0f * x * x * x * x * x : 1.0f - std::pow(-2.0f * x + 2.0f, 5.0f) / 2.0f;
}
void init_scene(const cv::Size& sz) {
static void init_scene(const cv::Size& sz) {
load_shader();
load_buffer_data();
@ -265,16 +206,16 @@ void init_scene(const cv::Size& sz) {
center_x_hdl = glGetUniformLocation(shader_program_hdl, "center_x");
center_y_hdl = glGetUniformLocation(shader_program_hdl, "center_y");
glViewport(0, 0, WIDTH, HEIGHT);
glViewport(0, 0, sz.width, sz.height);
}
void render_scene(const cv::Size& sz) {
static void render_scene() {
// glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// glClear(GL_COLOR_BUFFER_BIT);
if(zoom >= 1) {
if (zoom >= 1) {
zoom_incr = -0.01;
iterations = 0;
} else if(zoom < 2.5e-06) {
} else if (zoom < 2.5e-06) {
zoom_incr = +0.01;
iterations = 0;
}
@ -285,11 +226,11 @@ void render_scene(const cv::Size& sz) {
glUniform1i(max_iterations_hdl, max_iterations);
glUniform1f(center_y_hdl, center_y);
glUniform1f(center_x_hdl, center_x);
if(!manual_navigation) {
zoom+=zoom_incr;
if (!manual_navigation) {
zoom += zoom_incr;
glUniform1f(zoom_hdl, easeInOutQuint(zoom));
} else {
zoom = 1.0 / pow(zoom_factor,5.0f);
zoom = 1.0 / pow(zoom_factor, 5.0f);
glUniform1f(zoom_hdl, zoom);
}
@ -299,7 +240,8 @@ void render_scene(const cv::Size& sz) {
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}
void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
#ifndef __EMSCRIPTEN__
static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
static cv::UMat resize;
static cv::UMat blur;
static cv::UMat dst16;
@ -309,7 +251,8 @@ void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
//Resize for some extra performance
cv::resize(dst, resize, cv::Size(), 0.5, 0.5);
//Cheap blur
cv::boxFilter(resize, resize, -1, cv::Size(ksize, ksize), cv::Point(-1,-1), true, cv::BORDER_REPLICATE);
cv::boxFilter(resize, resize, -1, cv::Size(ksize, ksize), cv::Point(-1, -1), true,
cv::BORDER_REPLICATE);
//Back to original size
cv::resize(resize, blur, src.size());
@ -320,70 +263,76 @@ void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) {
cv::bitwise_not(dst, dst);
}
#endif
cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Shader Demo");
void setup_gui(cv::Ptr<cv::viz::V4D> v4d) {
v4d->nanogui([](cv::viz::FormHelper& form){
form.makeDialog(5, 30, "Fractal");
form.makeGroup("Navigation");
form.makeFormVariable("Iterations", max_iterations, 3, 1000000, true, "", "How deeply to calculate the fractal.");
auto* cxVar = form.makeFormVariable("X", center_x, -1.0f, 1.0f, true, "", "The x location from -1.0 to 1.0");
cxVar->number_format("%.7g");
cxVar->set_value_increment(0.0000001);
cxVar->set_callback([&, cxVar](const float& value){
manual_navigation = true;
cxVar->set_value(value);
center_x = value;
});
auto* cyVar = form.makeFormVariable("Y", center_y, -1.0f, 1.0f, true, "", "The y location from -1.0 to 1.0");
cyVar->number_format("%.7g");
cyVar->set_value_increment(0.0000001);
cyVar->set_callback([&,cyVar](const float &value) {
manual_navigation = true;
cyVar->set_value(value);
center_y = value;
});
auto* czVar = form.makeFormVariable("Zoom", zoom_factor, 1.0f, 1000000.0f, true, "", "How much to zoom in on the fractal");
czVar->set_callback([&,czVar](const float &value) {
manual_navigation = true;
czVar->set_value(value);
zoom_factor = value;
});
static void setup_gui(cv::Ptr<cv::viz::V4D> v4dMain) {
v4dMain->nanogui([](cv::viz::FormHelper& form) {
form.makeDialog(5, 30, "Fractal");
form.makeGroup("Navigation");
form.makeFormVariable("Iterations", max_iterations, 3, 1000000, true, "","How deeply to calculate the fractal." );
auto* cxVar = form.makeFormVariable("X", center_x, -1.0f, 1.0f, true, "",
"The x location from -1.0 to 1.0");
cxVar->number_format("%.7g");
cxVar->set_value_increment(0.0000001);
cxVar->set_callback([&, cxVar](const float& value) {
manual_navigation = true;
cxVar->set_value(value);
center_x = value;
});
auto* cyVar = form.makeFormVariable("Y", center_y, -1.0f, 1.0f, true, "",
"The y location from -1.0 to 1.0");
cyVar->number_format("%.7g");
cyVar->set_value_increment(0.0000001);
cyVar->set_callback([&, cyVar](const float& value) {
manual_navigation = true;
cyVar->set_value(value);
center_y = value;
});
auto* czVar = form.makeFormVariable("Zoom", zoom_factor, 1.0f, 1000000.0f, true, "",
"How much to zoom in on the fractal");
czVar->set_callback([&, czVar](const float& value) {
manual_navigation = true;
czVar->set_value(value);
zoom_factor = value;
});
#ifndef __EMSCRIPTEN__
form.makeGroup("Glow");
auto* kernelSize = form.makeFormVariable("Kernel Size", glow_kernel_size, 1, 127, true, "", "Intensity of glow defined by kernel size");
kernelSize->set_callback([=](const int& k) {
static int lastKernelSize = glow_kernel_size;
if(k == lastKernelSize)
return;
if(k <= lastKernelSize) {
glow_kernel_size = std::max(int(k % 2 == 0 ? k - 1 : k), 1);
} else if(k > lastKernelSize)
glow_kernel_size = std::max(int(k % 2 == 0 ? k + 1 : k), 1);
lastKernelSize = k;
kernelSize->set_value(glow_kernel_size);
});
form.makeGroup("Glow");
auto* kernelSize = form.makeFormVariable("Kernel Size", glow_kernel_size, 1, 127, true, "",
"Intensity of glow defined by kernel size");
kernelSize->set_callback([=](const int& k) {
static int lastKernelSize = glow_kernel_size;
if (k == lastKernelSize)
return;
if (k <= lastKernelSize) {
glow_kernel_size = std::max(int(k % 2 == 0 ? k - 1 : k), 1);
} else if (k > lastKernelSize)
glow_kernel_size = std::max(int(k % 2 == 0 ? k + 1 : k), 1);
lastKernelSize = k;
kernelSize->set_value(glow_kernel_size);
});
#endif
form.makeGroup("Color");
form.makeColorPicker("Color", base_color_val, "The base color of the fractal visualization",[&](const nanogui::Color &c) {
base_color_val[0] = c[0];
base_color_val[1] = c[1];
base_color_val[2] = c[2];
});
form.makeFormVariable("Alpha", alpha, 0.0f, 1.0f, true, "", "The opacity of the fractal visualization");
form.makeFormVariable("Contrast boost", contrast_boost, 1, 255, true, "", "Boost contrast by this factor");
form.makeGroup("Color");
form.makeColorPicker("Color", base_color_val, "The base color of the fractal visualization",
[&](const nanogui::Color& c) {
base_color_val[0] = c[0];
base_color_val[1] = c[1];
base_color_val[2] = c[2];
});
form.makeFormVariable("Alpha", alpha, 0.0f, 1.0f, true, "",
"The opacity of the fractal visualization");
form.makeFormVariable("Contrast boost", contrast_boost, 1, 255, true, "",
"Boost contrast by this factor");
});
}
bool iteration() {
static bool iteration() {
//ignore failed capture attempts
v4d->capture();
@ -397,7 +346,7 @@ bool iteration() {
//To slow for WASM but works
#ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL
v4d->fb([](cv::UMat &frameBuffer) {
v4d->fb([](cv::UMat& frameBuffer) {
//Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, glow_kernel_size);
});
@ -413,16 +362,19 @@ bool iteration() {
return v4d->display();
}
int main(int argc, char **argv) {
using namespace cv::viz;
try {
#ifndef __EMSCRIPTEN__
if(argc != 2) {
cerr << "Usage: shader-demo <video-file>" << endl;
exit(1);
}
int main(int argc, char** argv) {
if (argc != 2) {
cerr << "Usage: shader-demo <video-file>" << endl;
exit(1);
}
#else
int main() {
#endif
if(!v4d->isOffscreen()) {
try {
using namespace cv::viz;
if (!v4d->isOffscreen()) {
v4d->setVisible(true);
setup_gui(v4d);
}
@ -434,7 +386,8 @@ int main(int argc, char **argv) {
#ifndef __EMSCRIPTEN__
Source src = makeCaptureSource(argv[1]);
v4d->setSource(src);
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);
#else
Source src = makeCaptureSource(WIDTH, HEIGHT);
@ -442,7 +395,7 @@ int main(int argc, char **argv) {
#endif
v4d->run(iteration);
} catch(std::exception& ex) {
} catch (std::exception& ex) {
cerr << "Exception: " << ex.what() << endl;
}
return 0;

@ -1,6 +1,6 @@
#include <opencv2/v4d/v4d.hpp>
int main(int argc, char** argv) {
int main() {
using namespace cv;
using namespace cv::viz;

@ -1,6 +1,6 @@
#include <opencv2/v4d/v4d.hpp>
int main(int argc, char** argv) {
int main() {
using namespace cv;
using namespace cv::viz;

@ -11,85 +11,29 @@
constexpr long unsigned int WIDTH = 1920;
constexpr long unsigned int HEIGHT = 1080;
constexpr double FPS = 60;
constexpr bool OFFSCREEN = false;
#ifndef __EMSCRIPTEN__
constexpr double FPS = 60;
constexpr const char* OUTPUT_FILENAME = "video-demo.mkv";
#endif
const unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT));
const int GLOW_KERNEL_SIZE = std::max(int(DIAG / 138 % 2 == 0 ? DIAG / 138 + 1 : DIAG / 138),
1);
const int GLOW_KERNEL_SIZE = std::max(int(DIAG / 138 % 2 == 0 ? DIAG / 138 + 1 : DIAG / 138), 1);
using std::cerr;
using std::endl;
cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT),
cv::Size(WIDTH, HEIGHT), OFFSCREEN, "Video Demo");
GLuint vbo_cube_vertices, vbo_cube_colors;
GLuint ibo_cube_elements;
GLuint program;
GLint attribute_coord3d, attribute_v_color;
GLint uniform_mvp;
GLuint init_shader(const char* vShader, const char* fShader, const char* outputAttributeName) {
struct Shader {
GLenum type;
const char* source;
} shaders[2] = { { GL_VERTEX_SHADER, vShader }, { GL_FRAGMENT_SHADER, fShader } };
GLuint program = glCreateProgram();
for (int i = 0; i < 2; ++i) {
Shader& s = shaders[i];
GLuint shader = glCreateShader(s.type);
glShaderSource(shader, 1, (const GLchar**) &s.source, NULL);
glCompileShader(shader);
GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
std::cerr << " failed to compile:" << std::endl;
GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetShaderInfoLog(shader, logSize, NULL, logMsg);
std::cerr << logMsg << std::endl;
delete[] logMsg;
exit (EXIT_FAILURE);
}
glAttachShader(program, shader);
}
#ifndef OPENCV_V4D_USE_ES3
/* Link output */
glBindFragDataLocation(program, 0, outputAttributeName);
#endif
/* link and error check */
glLinkProgram(program);
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked) {
std::cerr << "Shader program failed to link" << std::endl;
GLint logSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog(program, logSize, NULL, logMsg);
std::cerr << logMsg << std::endl;
delete[] logMsg;
exit (EXIT_FAILURE);
}
const unsigned int triangles = 12;
const unsigned int vertices_index = 0;
const unsigned int colors_index = 1;
unsigned int shader_program;
unsigned int vao;
unsigned int uniform_transform;
/* use program object */
glUseProgram(program);
static cv::Ptr<cv::viz::V4D> v4d = cv::viz::V4D::make(cv::Size(WIDTH, HEIGHT), cv::Size(WIDTH, HEIGHT),
OFFSCREEN, "Cube Demo");
return program;
}
//mandelbrot shader code adapted from my own project: https://github.com/kallaballa/FractalDive#after
void load_shader() {
static GLuint load_shader() {
#ifndef OPENCV_V4D_USE_ES3
const string shaderVersion = "330";
#else
@ -99,148 +43,132 @@ void load_shader() {
const string vert =
" #version " + shaderVersion
+ R"(
attribute vec3 coord3d;
attribute vec3 v_color;
uniform mat4 mvp;
varying vec3 f_color;
void main(void) {
gl_Position = mvp * vec4(coord3d, 1.0);
f_color = v_color;
precision lowp float;
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 vertex_color;
uniform mat4 transform;
out vec3 color;
void main() {
gl_Position = transform * vec4(pos, 1.0);
color = vertex_color;
}
)";
const string frag =
" #version " + shaderVersion
+ R"(
varying vec3 f_color;
precision lowp float;
in vec3 color;
void main(void) {
gl_FragColor = vec4(f_color.r, f_color.g, f_color.b, 1.0);
out vec4 frag_color;
void main() {
frag_color = vec4(color, 1.0);
}
)";
cerr << "##### Vertex Shader #####" << endl;
cerr << vert << endl;
return cv::viz::init_shader(vert.c_str(), frag.c_str(), "fragColor");
}
static void init_scene() {
glEnable (GL_DEPTH_TEST);
cerr << "##### Fragment Shader #####" << endl;
cerr << frag << endl;
float vertices[] = {
// Front face
0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5,
program = init_shader(vert.c_str(), frag.c_str(), "fragColor");
}
// Back face
0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, };
float vertex_colors[] = { 1.0, 0.4, 0.6, 1.0, 0.9, 0.2, 0.7, 0.3, 0.8, 0.5, 0.3, 1.0,
0.2, 0.6, 1.0, 0.6, 1.0, 0.4, 0.6, 0.8, 0.8, 0.4, 0.8, 0.8, };
int init_resources() {
GLfloat cube_vertices[] = {
// front
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
// back
-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, };
glGenBuffers(1, &vbo_cube_vertices);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
GLfloat cube_colors[] = {
// front colors
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0,
// back colors
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, };
glGenBuffers(1, &vbo_cube_colors);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_colors);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_colors), cube_colors, GL_STATIC_DRAW);
GLushort cube_elements[] = {
// front
unsigned short triangle_indices[] = {
// Front
0, 1, 2, 2, 3, 0,
// top
// Right
0, 3, 7, 7, 4, 0,
// Bottom
2, 6, 7, 7, 3, 2,
// Left
1, 5, 6, 6, 2, 1,
// back
7, 6, 5, 5, 4, 7,
// bottom
4, 0, 3, 3, 7, 4,
// left
4, 5, 1, 1, 0, 4,
// right
3, 2, 6, 6, 7, 3, };
glGenBuffers(1, &ibo_cube_elements);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);
GLint link_ok = GL_FALSE;
GLuint vs, fs;
load_shader();
const char* attribute_name;
attribute_name = "coord3d";
attribute_coord3d = glGetAttribLocation(program, attribute_name);
if (attribute_coord3d == -1) {
fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
return 0;
}
attribute_name = "v_color";
attribute_v_color = glGetAttribLocation(program, attribute_name);
if (attribute_v_color == -1) {
fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
return 0;
}
const char* uniform_name;
uniform_name = "mvp";
uniform_mvp = glGetUniformLocation(program, uniform_name);
if (uniform_mvp == -1) {
fprintf(stderr, "Could not bind uniform %s\n", uniform_name);
return 0;
}
return 1;
}
// Back
4, 7, 6, 6, 5, 4,
void init_scene(const cv::Size& sz) {
init_resources();
glEnable (GL_BLEND);
glEnable (GL_DEPTH_TEST);
//glDepthFunc(GL_LESS);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Top
5, 1, 0, 0, 4, 5, };
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
unsigned int triangles_ebo;
glGenBuffers(1, &triangles_ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangles_ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof triangle_indices, triangle_indices,
GL_STATIC_DRAW);
unsigned int verticies_vbo;
glGenBuffers(1, &verticies_vbo);
glBindBuffer(GL_ARRAY_BUFFER, verticies_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(vertices_index, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(vertices_index);
unsigned int colors_vbo;
glGenBuffers(1, &colors_vbo);
glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof vertex_colors, vertex_colors, GL_STATIC_DRAW);
glVertexAttribPointer(colors_index, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(colors_index);
// Unbind to prevent accidental modification
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
shader_program = load_shader();
uniform_transform = glGetUniformLocation(shader_program, "transform");
}
void render_scene(const cv::Size& sz) {
glClear (GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
// glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glEnableVertexAttribArray(attribute_coord3d);
// Describe our vertices array to OpenGL (it can't guess its format automatically)
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_vertices);
glVertexAttribPointer(attribute_coord3d, // attribute
3, // number of elements per vertex, here (x,y,z)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
glEnableVertexAttribArray(attribute_v_color);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_colors);
glVertexAttribPointer(attribute_v_color, // attribute
3, // number of elements per vertex, here (R,G,B)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
/* Push each element in buffer_vertices to the vertex shader */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
int size;
glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(attribute_coord3d);
glDisableVertexAttribArray(attribute_v_color);
static void render_scene() {
glClearColor(0.1, 0.12, 0.2, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_program);
float angle = fmod(double(cv::getTickCount()) / double(cv::getTickFrequency()), 2 * M_PI);
float scale = 0.25;
cv::Matx44f scaleMat(scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0,
0.0, 1.0);
cv::Matx44f rotXMat(1.0, 0.0, 0.0, 0.0, 0.0, cos(angle), -sin(angle), 0.0, 0.0, sin(angle),
cos(angle), 0.0, 0.0, 0.0, 0.0, 1.0);
cv::Matx44f rotYMat(cos(angle), 0.0, sin(angle), 0.0, 0.0, 1.0, 0.0, 0.0, -sin(angle), 0.0,
cos(angle), 0.0, 0.0, 0.0, 0.0, 1.0);
cv::Matx44f rotZMat(cos(angle), -sin(angle), 0.0, 0.0, sin(angle), cos(angle), 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
cv::Matx44f transform = scaleMat * rotXMat * rotYMat * rotZMat;
glUniformMatrix4fv(uniform_transform, 1, GL_FALSE, transform.val);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_SHORT, NULL);
}
void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
#ifndef __EMSCRIPTEN__
static void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
static cv::UMat resize;
static cv::UMat blur;
static cv::UMat dst16;
@ -262,26 +190,27 @@ void glow_effect(const cv::UMat& src, cv::UMat& dst, const int ksize) {
cv::bitwise_not(dst, dst);
}
#endif
bool iteration() {
static bool iteration() {
using namespace cv::viz;
if (!v4d->capture())
return false;
//Render using OpenGL
v4d->gl(render_scene);
//If we have OpenCL and maybe even CL-GL sharing then this is faster than the glow shader. Without OpenCL this is very slow.
#ifndef __EMSCRIPTEN__
//Aquire the frame buffer for use by OpenCL
v4d->fb([&](cv::UMat& frameBuffer) {
//Glow effect (OpenCL)
glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE);
});
v4d->write();
#endif
updateFps(v4d, true);
v4d->write();
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
if (!v4d->display())
return false;
@ -289,13 +218,16 @@ bool iteration() {
return true;
}
#ifndef __EMSCRIPTEN__
int main(int argc, char** argv) {
using namespace cv::viz;
if (argc != 2) {
cerr << "Usage: video-demo <video-file>" << endl;
exit(1);
}
#else
int main() {
#endif
using namespace cv::viz;
if (!v4d->isOffscreen())
v4d->setVisible(true);

@ -1,6 +1,10 @@
#include <opencv2/v4d/v4d.hpp>
#ifndef __EMSCRIPTEN__
int main(int argc, char** argv) {
#else
int main() {
#endif
using namespace cv;
using namespace cv::viz;

@ -17,8 +17,8 @@ FrameBufferContext::FrameBufferContext(const FrameBufferContext& other) : FrameB
FrameBufferContext::FrameBufferContext(const cv::Size& frameBufferSize, bool offscreen,
const string& title, int major, int minor, bool compat, int samples, bool debug) :
frameBufferSize_(frameBufferSize), offscreen_(offscreen), title_(title), major_(major), minor_(
minor), compat_(compat), samples_(samples), debug_(debug) {
offscreen_(offscreen), title_(title), major_(major), minor_(
minor), compat_(compat), samples_(samples), debug_(debug), frameBufferSize_(frameBufferSize) {
if (glfwInit() != GLFW_TRUE)
assert(false);
@ -127,7 +127,10 @@ FrameBufferContext::~FrameBufferContext() {
}
void FrameBufferContext::toGLTexture2D(cv::UMat& u, cv::ogl::Texture2D& texture) {
#ifndef __EMSCRIPTEN__
#ifdef __EMSCRIPTEN__
CV_UNUSED(u);
CV_UNUSED(texture);
#else
using namespace cv::ocl;
cl_int status = 0;
@ -162,7 +165,10 @@ void FrameBufferContext::toGLTexture2D(cv::UMat& u, cv::ogl::Texture2D& texture)
}
void FrameBufferContext::fromGLTexture2D(const cv::ogl::Texture2D& texture, cv::UMat& u) {
#ifndef __EMSCRIPTEN__
#ifdef __EMSCRIPTEN__
CV_UNUSED(u);
CV_UNUSED(texture);
#else
using namespace cv::ocl;
const int dtype = CV_8UC4;

@ -52,6 +52,8 @@ unsigned int init_shader(const char* vShader, const char* fShader, const char* o
#ifndef OPENCV_V4D_USE_ES3
/* Link output */
glBindFragDataLocation(program, 0, outputAttributeName);
#else
CV_UNUSED(outputAttributeName);
#endif
/* link and error check */
glLinkProgram(program);
@ -170,6 +172,7 @@ static bool signal_handlers_installed = false;
* @param ignore We ignore the signal number
*/
static void request_finish(int ignore) {
CV_UNUSED(ignore);
finish_requested = true;
}
@ -213,7 +216,7 @@ void updateFps(cv::Ptr<cv::viz::V4D> v4d, bool graphical) {
}
if (graphical) {
v4d->nvg([&](const cv::Size& size) {
v4d->nvg([&]() {
using namespace cv;
string text = "FPS: " + std::to_string(fps);
nvg::beginPath();
@ -260,18 +263,6 @@ Source makeVaSource(const string& inputFilename, const int vaDeviceIndex) {
return !frame.empty();
}, fps);
}
#else
Sink makeVaSink(const string &outputFilename, const int fourcc, const float fps, const cv::Size &frameSize, const int vaDeviceIndex) {
return Sink([=](const cv::InputArray& frame){
return false;
});
}
Source makeVaSource(const string &inputFilename, const int vaDeviceIndex) {
return Source([=](cv::OutputArray& frame){
return false;
}, 0);
}
#endif
#ifndef __EMSCRIPTEN__

@ -13,7 +13,7 @@ namespace viz {
namespace detail {
void glfw_error_callback(int error, const char* description) {
fprintf(stderr, "GLFW Error: %s\n", description);
fprintf(stderr, "GLFW Error: (%d) %s\n", error, description);
}
bool contains_absolute(nanogui::Widget* w, const nanogui::Vector2i& p) {
@ -22,6 +22,17 @@ bool contains_absolute(nanogui::Widget* w, const nanogui::Vector2i& p) {
}
}
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);
}
}
cv::Scalar colorConvert(const cv::Scalar& src, cv::ColorConversionCodes code) {
cv::Mat tmpIn(1, 1, CV_8UC3);
cv::Mat tmpOut(1, 1, CV_8UC3);
@ -223,6 +234,14 @@ cv::Size V4D::getVideoFrameSize() {
return clva().getVideoFrameSize();
}
void V4D::gl(std::function<void()> fn) {
#ifndef __EMSCRIPTEN__
detail::CLExecScope_t scope(fb().getCLExecContext());
#endif
detail::FrameBufferContext::GLScope glScope(fb());
fn();
}
void V4D::gl(std::function<void(const cv::Size&)> fn) {
auto fbSize = getFrameBufferSize();
#ifndef __EMSCRIPTEN__
@ -236,6 +255,13 @@ void V4D::fb(std::function<void(cv::UMat&)> fn) {
fb().execute(fn);
}
void V4D::nvg(std::function<void()> fn) {
nvg().render([=](const cv::Size& sz){
CV_UNUSED(sz);
fn();
});
}
void V4D::nvg(std::function<void(const cv::Size&)> fn) {
nvg().render(fn);
}
@ -247,7 +273,7 @@ void V4D::nanogui(std::function<void(FormHelper& form)> fn) {
}
#ifdef __EMSCRIPTEN__
void do_frame(void* void_fn_ptr) {
static void do_frame(void* void_fn_ptr) {
auto* fn_ptr = reinterpret_cast<std::function<bool()>*>(void_fn_ptr);
if (fn_ptr) {
auto& fn = *fn_ptr;
@ -549,6 +575,8 @@ bool V4D::isStretching() {
void V4D::setDefaultKeyboardEventCallback() {
setKeyboardEventCallback([&](int key, int scancode, int action, int modifiers) {
CV_UNUSED(scancode);
CV_UNUSED(modifiers);
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
setOffscreen(!isOffscreen());
return true;

Loading…
Cancel
Save