Reputation: 8173
Using several thousands of viz::Widget3D in OpenCV is very slow. I tried v3.4.3 and v4.0.0 on Windows with Visual Studio 2017. This code snippet takes over 5s to execute the timed part (t0
to t1
) and viewing is very choppy afterwards:
using namespace std;
using namespace cv;
int main()
{
constexpr double n = 100;
viz::Viz3d window("Viz3d");
window.setFullScreen();
window.showWidget("Coordinate Widget", viz::WCoordinateSystem());
window.spinOnce();
auto t0 = chrono::high_resolution_clock::now();
for (double x = 0; x < n; x += 1)
for (double y = 0; y < n; y += 1)
window.showWidget(to_string(x+y*n), viz::WArrow({x, y, 0}, {x+1, y+1, 0}, 0.02, viz::Color::bluberry()));
auto t1 = chrono::high_resolution_clock::now();
window.spin();
fmt::print("\nTime: {}ms", chrono::duration_cast<chrono::milliseconds>(t1-t0).count());
fmt::print("\nVersion {}.{}.{}{}\n", CV_VERSION_MAJOR, CV_VERSION_MINOR, CV_VERSION_REVISION, CV_VERSION_STATUS);
return 0;
}
It seems that widget management imposes a huge overhead. Is there any other way to display thousands of widgets (text, lines, arrow) with low latency? I tried viz::WWidgetMerger
and it's even slower.
EDIT
BTW, I need only "immediate" mode rendering. I'm not modifying the widgets after they are shown.
Upvotes: 2
Views: 603
Reputation: 21
If you have thousands of widgets, creating a single WidgetMerger will be ungodly slow when adding all the widgets together (if you were to visualize the time of each individual addition you will see the exponential slowdown).
However, if you instead have multiple mergers it should be smooth with absolutely no choppiness when displaying, while only being a little bit slower on creation.
You can try doing something similar to this:
std::vector<viz::WWidgetMerger> mergers(n);
for (double x = 0; x < n; x += 1) {
viz::WWidgetMerger merger = mergers[x];
for (double y = 0; y < n; y += 1) {
merger.addWidget(viz::WArrow({x, y, 0}, {x+1, y+1, 0}, 0.02, viz::Color::bluberry()));
}
merger.finalize();
window.showWidget("merger_" + std::to_string(x), merger);
}
Performance differences:
Your code as is: Time: 2522ms
extremely choppy to the point of being almost unusable.
Using multiple mergers: Time: 6097ms
buttery smooth, no choppiness
Using a single merger: Time > 5 minutes. I didn't even wait for it to finish it was taking so long.
So while using multiple mergers is a slight slowdown initially when creating the widgets, for the display performance, I find it to be worth it.
Upvotes: 2