Isn't there a OpenCV Cuda function similar to findContours? - c++

There are several OpenCV CPU functions which have a direct CUDA counterpart like cv::cvtColor & cv::cuda::cvtColor.
But I found no direct or indirect (GPU) Cuda counterpart for cv::findContours CPU.
Isn't there a OpenCV Cuda function similar to findContours? Or does findContours work on both cv::Mat and cv::cuda::GpuMat?

Unfortunately, not. Not even in the latest OpenCV 3.2.0 version. But they have this update, as shown here: https://github.com/opencv/opencv/wiki/ChangeLog
findContours can now find contours on a 32-bit integer image of labels (not only on a black-and-white 8-bit image). This is a step towards more convenient connected component analysis.

No. OpenCV 4.6.0 does not have it.
Nobody has dared to implement this with CUDA for years.

Related

Container type with OpenCV and OpenCL

I want to call cv::findCountours on some cv::UMat (OpenCL activated) and get the results into std::vector<std::vector<cv::Point>>.
std::vector<std::vector<cv::Point>> contours;
cv::findContours(frame_umat, contours, cv::RETR_LIST, cv::ContourApproximationModes::CHAIN_APPROX_SIMPLE);
Will OpenCV still able to optimise it using OpenCL even if I am using std::vector? Is there any advantage of using a special container like for example cv::UMat as a container(not an image)?
By tracing OpenCV cv::findContours function, I realized that it is not optimised using OpenCL at all (not CUDA also). The only implementation it has is SSE2 as far as I found in OpenCV 3.1

Unexpected camera calibration results with OpenCV over JPEG images and EXIF orientation

I am exploiting OpenCV to calibrate a set of images. I am using the standard function cv::calibrateCamera offered by OpenCV, nothing special here. The images are in JPEG format, and the EXIF Orientation flag is set (and it can be != 1).
I have noticed that if the images are not all top-left oriented (Orientation == 1) the calibration result is wrong, usually resulting in a very high RMS error. On the contrary, if I manually correct the orientation (using mogrify or exiftool, for instance), the result is as expected.
Have you ever encountered this kind of behavior? Can you please explain me why this is happening?
As a side note, I am using OpenCV 3.1 on a Mac OSX El Capitan, installed via Homebrew. Code is in C++.
are you using imread or cvLoadImage? imread for opencv 3.1 seems to handle exif correctly, but cvLoadImage not. See the following opencv bug https://github.com/opencv/opencv/issues/6673

CUDA equivalent of estimateRigidTransform in OpenCV 3

I'm working on a video stabilisation project using OpenCV, and I've got a CPU implementation working but the performance needs improvement so I'm trying to move most of the processing to the GPU.
The current implementation primarily uses these four OpenCV functions:
cv::goodFeaturesToTrack
cv::calcOpticalFlowPyrLK
cv::estimateRigidTransform
cv::warpAffine
So far I've found the following equivalents on the GPU:
cv::cuda::createGoodFeaturesToTrackDetector
cv::cuda::SparsePyrLKOpticalFlow
cv::cuda::warpAffine
Is there a CUDA equivalent of estimateRigidTransform?
OpenCV doesn't have implementation for estimateRigidTransform on CUDA.
There is opencv based project on github, which has functions for computing homographies and estimating rigid transforms: https://github.com/danielsuo/cuSIFT
Here is function you need:
https://github.com/danielsuo/cuSIFT/blob/master/extras/rigidTransform.cu

Does OpenGL display image faster than OpenCV?

I am using OpenCV to show image on the projector. But it seems the cv::imshow is not fast enough or maybe the data transfer is slow from my CPU to GPU then to projector, so I wonder if there is a faster way to display than OpenCV?
I considered OpenGL, since OpenGL directly uses GPU, the command may be faster than from CPU which is used by OpenCV. Correct me if I am wrong.
OpenCV already supports OpenGL for image output by itself. No need to write this yourself!
See the documentation:
http://docs.opencv.org/modules/highgui/doc/user_interface.html#imshow
http://docs.opencv.org/modules/highgui/doc/user_interface.html#namedwindow
Create the window first with namedWindow, where you can pass the WINDOW_OPENGL flag.
Then you can even use OpenGL buffers or GPU matrices as input to imshow (the data never leaves the GPU). But it will also use OpenGL to show regular matrix data.
Please note:
To enable OpenGL support, configure OpenCV using CMake with
WITH_OPENGL=ON . Currently OpenGL is supported only with WIN32, GTK
and Qt backends on Windows and Linux (MacOS and Android are not
supported). For GTK backend gtkglext-1.0 library is required.
Note that this is OpenCV 2.4.8 and this functionality has changed quite recently. I know there was OpenGL support in earlier versions in conjunction with the Qt backend, but I don't remember when it was introduced.
About the performance: It is a quite popular optimization in the CV community to output images using OpenGL, especially when outputting video sequences.
OpenGL is optimised for rendering images, so it's likely faster. It really depends if the OpenCV implementation uses any GPU acceleration AND if the bottleneck is on rendering side of things.
Have you tried GPU accelerated OpenCV? - http://opencv.org/platforms/cuda.html
How big is the image you are displaying? How long does it take to display the image using cv::imshow now?
I know it's an old question, but I happened to have exactly the same problem. And from my observations I've concluded that the root of the problem is the projector's own latency, especially if one is using an older model.
How have I concluded it?
I displayed the same video sequence with cv::imshow() on the laptop monitor and on the projector. Then I waved my hand. It was obvious, that projector introduces significant latency.
To double-check, I've opended a webcam video, waved my hand in front of it and observed the difference on the monitor and on the projector. Webcam does no processing, no opencv operations, so in my understanding the only thing that would explain the latency would be the projector itself.

Drawing in OpenCV with OpenGL

OpenCV library, when compiled with GPU and OpenGL support, allows for displaying images with OpenGL. For example, video_reader.cpp (located in gpu samples) uses OpenGL to render display graphics directly from cv::gpu::GpuMat.
cv::gpu::GpuMat d_frame;
namedWindow("OpenGL", WINDOW_OPENGL);
cv::gpu::VideoReader_GPU d_reader(fname);
d_reader.dumpFormat(std::cout);
if (!d_reader.read(d_frame))
break;
cv::imshow("GPU", d_frame);
This is a very useful feature. However, it is not documented in the documentation on-line. For example, for namedWindow the flag WINDOW_OPENGL is not listed in the docs. Where can I find the documentation for OpenGL -related functionality of OpenCV?
The documentation is not very complete for 2.4.5. I don't think there is any more documentation than what you see on http://docs.opencv.org.
There are older documentation, such as http://opencv.willowgarage.com/documentation/cpp/ for 2.1, but I didn't find it having the documentation for the flag that you wanted.
OpenCV/OpenGL interop documentation
https://docs.opencv.org/4.x/d2/d3c/group__core__opengl.html
Highgui/OpenGL documentation
https://docs.opencv.org/4.x/df/d24/group__highgui__opengl.html
Especially the second link gives you two easy options for rendering.
imshow with a Texture2D object
setOpenGlDrawCallback() (https://docs.opencv.org/4.x/df/d24/group__highgui__opengl.html#gaf80dcbc168a6ce40f6d1ad9d79a10bb8) which allows you to draw on top of a nameWindow("OpenGL Window", WINDOW_OPENGL) using OpenGL.
The function
cv::imshow(const & string, cv::InputArray)
does not natively support gpu matrices, but supports GPU matrices by casting.
i.e. anything which supports a cv::Mat on its input should also support cv::gpu::GpuMat. I presume this means that when you call the function, it will automatically download the matrix to a cv::Mat and go from there, i.e. your imshow function call is not drawing directly gpu->gpu, but going gpu->cpu->gpu.