diff --git a/modules/viz2d/doc/custom_source_and_sink.png b/modules/viz2d/doc/custom_source_and_sink.png new file mode 100644 index 000000000..475f3751d Binary files /dev/null and b/modules/viz2d/doc/custom_source_and_sink.png differ diff --git a/modules/viz2d/samples/cpp/custom_source_and_sink.cpp b/modules/viz2d/samples/cpp/custom_source_and_sink.cpp new file mode 100644 index 000000000..290bbeedb --- /dev/null +++ b/modules/viz2d/samples/cpp/custom_source_and_sink.cpp @@ -0,0 +1,69 @@ +#include +#include +#include + +using namespace cv; +using namespace cv::viz; + +constexpr int WIDTH = 1280; +constexpr int HEIGHT = 720; + +int main(int argc, char** argv) { + string hv = "Hello Rainbow!"; + Ptr v2d = Viz2D::make(Size(WIDTH, HEIGHT), "Video Editing"); + //Make a Source that generates rainbow frames. + Source src([=](cv::UMat& frame){ + static long cnt = 0; + + if(frame.empty()) + frame.create(v2d->getFrameBufferSize(), CV_8UC3); + frame = colorConvert(Scalar(cnt % 180, 128, 128, 255), COLOR_HLS2BGR); + + ++cnt; + if(cnt > std::numeric_limits().max() / 2.0) + cnt = 0; + return true; + }, 60.0f); + + //Make a Sink the saves each frame to a PNG file. + Sink sink([](const cv::UMat& frame){ + static long cnt = 0; + + try { + imwrite(std::to_string(cnt) + ".png", frame); + } catch(std::exception& ex) { + cerr << "Unable to write frame: " << ex.what() << endl; + return false; + } + + ++cnt; + if(cnt > std::numeric_limits().max() / 2.0) + cnt = 0; + + return true; + }); + + //Attach source and sink + v2d->setSource(src); + v2d->setSink(sink); + + v2d->run([=]() { + //Capture video from the Source + if(!v2d->capture()) + return false; //end of input video + + //Render "Hello Rainbow!" over the frame + v2d->nvg([=](const Size& sz) { + using namespace cv::viz::nvg; + + fontSize(40.0f); + fontFace("sans-bold"); + fillColor(Scalar(255, 0, 0, 255)); + textAlign(NVG_ALIGN_CENTER | NVG_ALIGN_TOP); + text(sz.width / 2.0, sz.height / 2.0, hv.c_str(), hv.c_str() + hv.size()); + }); + v2d->write(); //Write video to the Sink + return v2d->display(); //Display the framebuffer in the native window + }); +} + diff --git a/modules/viz2d/tutorials/06-custom_source_and_sink.markdown b/modules/viz2d/tutorials/06-custom_source_and_sink.markdown index d08aae235..41b187278 100644 --- a/modules/viz2d/tutorials/06-custom_source_and_sink.markdown +++ b/modules/viz2d/tutorials/06-custom_source_and_sink.markdown @@ -9,9 +9,9 @@ | Compatibility | OpenCV >= 4.7 | ## Reading and writing to Viz2D using custom Sources and Sinks -In the previous tutorial we used a default video source and a video sink to stream a video through Viz2D's framebuffer which can be manipulated using OpenGL or NanoVG - hence video editing. +In the previous tutorial we used a default video source and a video sink to stream a video through Viz2D which can be manipulated using OpenGL or NanoVG. In this example we are creating a custom Source that generates rainbow frames. For each time the Source is invoked the frame is colored a slightly different color. Additionally the custom Sink saves individual images instead of a video. @include samples/cpp/custom_source_and_sink.cpp -![The result](doc/video_editing.png) +![The result](doc/custom_source_and_sink.png)