1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin
2018-11-10 20:10:57 +00:00
90 changed files with 6261 additions and 6657 deletions
@@ -81,8 +81,8 @@ points.
Now an orientation is assigned to each keypoint to achieve invariance to image rotation. A
neighbourhood is taken around the keypoint location depending on the scale, and the gradient
magnitude and direction is calculated in that region. An orientation histogram with 36 bins covering
360 degrees is created. (It is weighted by gradient magnitude and gaussian-weighted circular window
with \f$\sigma\f$ equal to 1.5 times the scale of keypoint. The highest peak in the histogram is taken
360 degrees is created (It is weighted by gradient magnitude and gaussian-weighted circular window
with \f$\sigma\f$ equal to 1.5 times the scale of keypoint). The highest peak in the histogram is taken
and any peak above 80% of it is also considered to calculate the orientation. It creates keypoints
with same location and scale, but different directions. It contribute to stability of matching.
@@ -99,7 +99,7 @@ illumination changes, rotation etc.
Keypoints between two images are matched by identifying their nearest neighbours. But in some cases,
the second closest-match may be very near to the first. It may happen due to noise or some other
reasons. In that case, ratio of closest-distance to second-closest distance is taken. If it is
greater than 0.8, they are rejected. It eliminaters around 90% of false matches while discards only
greater than 0.8, they are rejected. It eliminates around 90% of false matches while discards only
5% correct matches, as per the paper.
So this is a summary of SIFT algorithm. For more details and understanding, reading the original
@@ -20,7 +20,7 @@ extract the moving foreground from static background.
If you have an image of background alone, like an image of the room without visitors, image of the road
without vehicles etc, it is an easy job. Just subtract the new image from the background. You get
the foreground objects alone. But in most of the cases, you may not have such an image, so we need
to extract the background from whatever images we have. It become more complicated when there are
to extract the background from whatever images we have. It becomes more complicated when there are
shadows of the vehicles. Since shadows also move, simple subtraction will mark that also as
foreground. It complicates things.
@@ -72,7 +72,7 @@ papers by Z.Zivkovic, "Improved adaptive Gaussian mixture model for background s
and "Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction"
in 2006. One important feature of this algorithm is that it selects the appropriate number of
gaussian distribution for each pixel. (Remember, in last case, we took a K gaussian distributions
throughout the algorithm). It provides better adaptibility to varying scenes due illumination
throughout the algorithm). It provides better adaptability to varying scenes due illumination
changes etc.
As in previous case, we have to create a background subtractor object. Here, you have an option of
@@ -75,10 +75,10 @@ solution.
( Check similarity of inverse matrix with Harris corner detector. It denotes that corners are better
points to be tracked.)
So from user point of view, idea is simple, we give some points to track, we receive the optical
So from the user point of view, the idea is simple, we give some points to track, we receive the optical
flow vectors of those points. But again there are some problems. Until now, we were dealing with
small motions. So it fails when there is large motion. So again we go for pyramids. When we go up in
the pyramid, small motions are removed and large motions becomes small motions. So applying
small motions, so it fails when there is a large motion. To deal with this we use pyramids. When we go up in
the pyramid, small motions are removed and large motions become small motions. So by applying
Lucas-Kanade there, we get optical flow along with the scale.
Lucas-Kanade Optical Flow in OpenCV
@@ -69,7 +69,7 @@ to an integer format. Then we use a simple look and the upper formula to calcula
No OpenCV specific stuff here.
Another issue is how do we measure time? Well OpenCV offers two simple functions to achieve this
@ref cv::getTickCount() and @ref cv::getTickFrequency() . The first returns the number of ticks of
cv::getTickCount() and cv::getTickFrequency() . The first returns the number of ticks of
your systems CPU from a certain event (like since you booted your system). The second returns how
many times your CPU emits a tick during a second. So to measure in seconds the number of time
elapsed between two operations is easy as:
@@ -98,7 +98,7 @@ example in case of an BGR color system:
Note that the order of the channels is inverse: BGR instead of RGB. Because in many cases the memory
is large enough to store the rows in a successive fashion the rows may follow one after another,
creating a single long row. Because everything is in a single place following one after another this
may help to speed up the scanning process. We can use the @ref cv::Mat::isContinuous() function to *ask*
may help to speed up the scanning process. We can use the cv::Mat::isContinuous() function to *ask*
the matrix if this is the case. Continue on to the next section to find an example.
The efficient way
@@ -155,7 +155,7 @@ elements in the image. Its basic usage is to specify the row and column number o
to access. During our earlier scanning methods you could already observe that is important through
what type we are looking at the image. It's no different here as you need to manually specify what
type to use at the automatic lookup. You can observe this in case of the gray scale images for the
following source code (the usage of the + @ref cv::at() function):
following source code (the usage of the + cv::Mat::at() function):
@snippet how_to_scan_images.cpp scan-random
@@ -169,12 +169,12 @@ new row pointer for what we use the C operator[] to acquire the column element.
If you need to do multiple lookups using this method for an image it may be troublesome and time
consuming to enter the type and the at keyword for each of the accesses. To solve this problem
OpenCV has a @ref cv::Mat_ data type. It's the same as Mat with the extra need that at definition
OpenCV has a cv::Mat_ data type. It's the same as Mat with the extra need that at definition
you need to specify the data type through what to look at the data matrix, however in return you can
use the operator() for fast access of items. To make things even better this is easily convertible
from and to the usual @ref cv::Mat data type. A sample usage of this you can see in case of the
from and to the usual cv::Mat data type. A sample usage of this you can see in case of the
color images of the upper function. Nevertheless, it's important to note that the same operation
(with the same runtime speed) could have been done with the @ref cv::at() function. It's just a less
(with the same runtime speed) could have been done with the cv::Mat::at function. It's just a less
to write for the lazy programmer trick.
The Core Function
@@ -183,7 +183,7 @@ The Core Function
This is a bonus method of achieving lookup table modification in an image. In image
processing it's quite common that you want to modify all of a given image values to some other value.
OpenCV provides a function for modifying image values, without the need to write the scanning logic
of the image. We use the @ref cv::LUT() function of the core module. First we build a Mat type of the
of the image. We use the cv::LUT() function of the core module. First we build a Mat type of the
lookup table:
@snippet how_to_scan_images.cpp table-init