calcopticalflowpyrlk function in opencv 3.0 - c++

I'm trying to track something in some frames. I know calcOpticalFlowPyrLK is supposed to be used for sparse tracking problems. However, I thought it wouldn't really hurt if I just try to track all pixels in the frames.
So my video frames are actually very stable(motions are barely visible by eyes), and calcopticalflowpyrlk works well for most pixels. But for some pixels it returns really big flow vectors(like [200,300]), which doesn't make sense.
And I also found a Matlab implementation that's using the same Pyramidal Lucas-Kanade algorithm, but this Matlab version doesn't return any crazy values.
So I'm wondering what is causing opencv function to return huge non-reasonable values. Is it because the matrix inversion is done differently?

Related

Most efficient way to blur an image in opencv

I am blurring the background of an image using the blur method. All the tutorials I have seen show the highest kernel size of (7,7). But that is not blurred enough for what I need it for.
I have used Size(33,33) and it works alright but I would like to go higher so currently I am using Size(77,77). Is this the most efficient way of blurring an image in OpenCV? And is it okay to go that high at all?
Another Idea is run the blur method more than once. with a kernel size of (7,7), but that doesn't seem like it is more efficient.
EDIT:
OpenCV version 3.2
Try cv::stackBlur().
It's an addition from v4.7.0. Its performance is almost flat, i.e. independent of kernel size. The pull request contains performance figures: https://github.com/opencv/opencv/pull/20379
GaussianBlur(sigmaX=22) (30 ms)
stackBlur(ksize=(101,101)) (0.4 ms)

OpenCV drawing vs SVG rendering performance

I need to render vector graphics very fast to use it in OpenCV (in nodejs).
Fastest way to render simple shapes like oval is to use OpenCV drawing functions.
In my multithreaded test program I have ~625 1-channel 512*512 Mat's with 1 random filled oval per second.
With fastest available in nodejs SVG to PNG renderer 'librsvg' I have only ~277 same Mat's per second. It's not fast enough for my purposes.
I found another SVG renderer lib based on OpenGL - SVGL, but I didn't test it's performance, there is no bindings for node, C++ only.
I will need to render much more complicated vector graphics than just one ellipse.
So I expect a lot of work if I will try to implement all the drawing functions I will need with OpenCV, and I am not sure if OpenCV performance will be still acceptable in case of complicated vector images.
"Complicated" I mean some hundreds of semi-transparent arcs, beziers or some kind of rounded polygons, not filled or filled with solid semi-transparent color or, possibly, with gradients. And I want to render it to pretty large Mat, may be 1024*768 or so.
SVG already has everything I need, but I don't know C++,
so it will(probably) also take a lot of time to implement bindings for SVGL, while I still don't know it's performance
May be there are some alternative opensource ways?

background extraction using OpenCv

I want to extract the background from a video but i don't want to use cv::bgsegm::BackgroundSubtractorMOG, cv::BackgroundSubtractorMOG2 these methods. because they using frame means. But I planed to use frame comparison method. Where i'm using first frame as background model and i plane to compere pixel values of next frames with first frame pixel values and if there is no change or change less than threshold it is background pixel. How can implement these using OpenCV and C++
Your question is too vague, I think. I can only give you some hints.
First, your approach is very simplistic. That's not bad. But from my experience, it won't give great results, even if you have a lot of control over your scene. Nevertheless, I do not want to hold you back if you want to make your own experiences.
You probably want to take a look at
Operations on Arrays in OpenCV
Basic Threshold Operations in OpenCV
Everything you need should be there. In particular, the absdiff operation and the threshold function (with binary threshold type) should be of interest.

FFT based image registration (optionally using OpenCV) in cpp?

I'm trying to align two images taken from a handheld camera.
At first, I was trying to use the OpenCV warpPerspective method based on SIFT/SURF feature points. The problem is the feature-extract & matching process may be extremely slow when the image quality is high (3000x4000). I tried to scale-down the image before find feature-points, the result is not as good as before.(The Mat generated from findHomography shouldn't be affected by scaling down the image, right?) And sometimes, due to lack of good feature point matches, the result is quite strange.
After searching on this topic, it seems that solving the problem in Fourier domain will speed up the registration process. And I've found this question which leads me to the code here.
The only problem is the code is written in python with numpy (not even using OpenCV), which makes it quite hard to re-written to C++ code using OpenCV (In OpenCV, I can only find dft and there's no fftshift nor fft stuff, I'm not quite familiar with NumPy, and I'm not brave enough to simply ignore the missing methods). So I'm wondering why there is not such a Fourier-domain image registration implementation using C++?
Can you guys give me some suggestion on how to implement one, or give me a link to the already implemented C++ version? Or help me to turn the python code into C++ code?
Big thanks!
I'm fairly certain that the FFT method can only recover a similarity transform, that is, only a (2d) rotation, translation and scale. Your results might not be that great using a handheld camera.
This is not quite a direct answer to your question, but, as a suggestion for a speed improvement, have you tried using a faster feature detector and descriptor? In OpenCV SIFT/SURF are some of the slowest methods they have for feature extraction/matching. You could try testing some of their other methods first, they all work quite well and are faster than SIFT/SURF. Especially if you use their FLANN-based matcher.
I've had to do this in the past with similar sized imagery, and using the binary descriptors OpenCV has increases the speed significantly.
If you need only shift you can use OpenCV's phasecorrelate

Speed up OpenCV

I am using OpenCV 2.4 (C++) for line finding on grayscale images. This involves some basic image processing steps like blurring, threshold, Canny edge detector, gradient filter or Hough transformation. I have to apply the line finding algorithm on thousands of images.
Is there a way to speed up the calculation considering the large number of images?
Does one of the following provide help? Intel TBB, IPP or OpenCV GPU?
I heard that OpenCV GPU can speed up calculations but data transfer is slowly. So using GPU might not be the right choice here?
Thank You!
EDIT:
Is there any sense in using parallel_for from TBB to speed up image processing? If I use a for loop like this:
for(int i=0; i<image_location.size();++i)
{
Mat img=imread(image_location[i]);
blur(img...);
threshold(img...);
...
}
Can I improve performance by using parallel_for instead? Can anyone provide examples how to use parallel_for including some opencv operations?
The scope of your question is virtually unbounded.
First of all, have you measured the performance of your application to detect the actual bottleneck(s) ? My guess would be the Hough transform, but who knows what else your code is doing. Now, if the Hough transform is the slow piece, and supposing OpenCV has a fast implementation of it, then this is the reason I tell you the question is problematic. Changing for a somewhat better implementation doesn't help much when you decide to increase your already large number of images, the problem is in the approach itself.
Do you really need to use Hough ? Maybe you could achieve something similar/better using morphological operators ? Are the images from some common domain ? Can you include examples of them ? Etc, etc.