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

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

This commit is contained in:
Alexander Alekhin
2018-05-21 16:20:14 +03:00
117 changed files with 4451 additions and 1135 deletions
@@ -32,11 +32,11 @@ Unspecified error: Can't create layer "layer_name" of type "MyType" in function
To import the model correctly you have to derive a class from cv::dnn::Layer with
the following methods:
@snippet dnn/custom_layers.cpp A custom layer interface
@snippet dnn/custom_layers.hpp A custom layer interface
And register it before the import:
@snippet dnn/custom_layers.cpp Register a custom layer
@snippet dnn/custom_layers.hpp Register a custom layer
@note `MyType` is a type of unimplemented layer from the thrown exception.
@@ -44,27 +44,27 @@ Let's see what all the methods do:
- Constructor
@snippet dnn/custom_layers.cpp MyLayer::MyLayer
@snippet dnn/custom_layers.hpp MyLayer::MyLayer
Retrieves hyper-parameters from cv::dnn::LayerParams. If your layer has trainable
weights they will be already stored in the Layer's member cv::dnn::Layer::blobs.
- A static method `create`
@snippet dnn/custom_layers.cpp MyLayer::create
@snippet dnn/custom_layers.hpp MyLayer::create
This method should create an instance of you layer and return cv::Ptr with it.
- Output blobs' shape computation
@snippet dnn/custom_layers.cpp MyLayer::getMemoryShapes
@snippet dnn/custom_layers.hpp MyLayer::getMemoryShapes
Returns layer's output shapes depends on input shapes. You may request an extra
memory using `internals`.
- Run a layer
@snippet dnn/custom_layers.cpp MyLayer::forward
@snippet dnn/custom_layers.hpp MyLayer::forward
Implement a layer's logic here. Compute outputs for given inputs.
@@ -74,7 +74,7 @@ the second invocation of `forward` will has the same data at `outputs` and `inte
- Optional `finalize` method
@snippet dnn/custom_layers.cpp MyLayer::finalize
@snippet dnn/custom_layers.hpp MyLayer::finalize
The chain of methods are the following: OpenCV deep learning engine calls `create`
method once then it calls `getMemoryShapes` for an every created layer then you
@@ -108,11 +108,11 @@ layer {
This way our implementation can look like:
@snippet dnn/custom_layers.cpp InterpLayer
@snippet dnn/custom_layers.hpp InterpLayer
Next we need to register a new layer type and try to import the model.
@snippet dnn/custom_layers.cpp Register InterpLayer
@snippet dnn/custom_layers.hpp Register InterpLayer
## Example: custom layer from TensorFlow
This is an example of how to import a network with [tf.image.resize_bilinear](https://www.tensorflow.org/versions/master/api_docs/python/tf/image/resize_bilinear)
@@ -185,11 +185,11 @@ Custom layers import from TensorFlow is designed to put all layer's `attr` into
cv::dnn::LayerParams but input `Const` blobs into cv::dnn::Layer::blobs.
In our case resize's output shape will be stored in layer's `blobs[0]`.
@snippet dnn/custom_layers.cpp ResizeBilinearLayer
@snippet dnn/custom_layers.hpp ResizeBilinearLayer
Next we register a layer and try to import the model.
@snippet dnn/custom_layers.cpp Register ResizeBilinearLayer
@snippet dnn/custom_layers.hpp Register ResizeBilinearLayer
## Define a custom layer in Python
The following example shows how to customize OpenCV's layers in Python.
@@ -5,6 +5,8 @@ This section contains tutorials about how to use the built-in graphical user int
- @subpage tutorial_trackbar
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.0
*Author:* Ana Huamán
@@ -1,11 +1,11 @@
Adding a Trackbar to our applications! {#tutorial_trackbar}
======================================
- In the previous tutorials (about *linear blending* and the *brightness and contrast
adjustments*) you might have noted that we needed to give some **input** to our programs, such
as \f$\alpha\f$ and \f$beta\f$. We accomplished that by entering this data using the Terminal
- Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (*highgui.hpp*)
for you. An example of this is a **Trackbar**
- In the previous tutorials (about @ref tutorial_adding_images and the @ref tutorial_basic_linear_transform)
you might have noted that we needed to give some **input** to our programs, such
as \f$\alpha\f$ and \f$beta\f$. We accomplished that by entering this data using the Terminal.
- Well, it is time to use some fancy GUI tools. OpenCV provides some GUI utilities (**highgui** module)
for you. An example of this is a **Trackbar**.
![](images/Adding_Trackbars_Tutorial_Trackbar.png)
@@ -24,26 +24,73 @@ Code
Let's modify the program made in the tutorial @ref tutorial_adding_images. We will let the user enter the
\f$\alpha\f$ value by using the Trackbar.
@add_toggle_cpp
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp)
@include cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp
@end_toggle
@add_toggle_java
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java)
@include java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java
@end_toggle
@add_toggle_python
This tutorial code's is shown lines below. You can also download it from
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py)
@include python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py
@end_toggle
Explanation
-----------
We only analyze the code that is related to Trackbar:
-# First, we load two images, which are going to be blended.
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp load
- First, we load two images, which are going to be blended.
-# To create a trackbar, first we have to create the window in which it is going to be located. So:
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp window
@add_toggle_cpp
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp load
@end_toggle
-# Now we can create the Trackbar:
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp create_trackbar
@add_toggle_java
@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java load
@end_toggle
Note the following:
@add_toggle_python
@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py load
@end_toggle
- To create a trackbar, first we have to create the window in which it is going to be located. So:
@add_toggle_cpp
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp window
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java window
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py window
@end_toggle
- Now we can create the Trackbar:
@add_toggle_cpp
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp create_trackbar
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java create_trackbar
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py create_trackbar
@end_toggle
Note the following (C++ code):
- Our Trackbar has a label **TrackbarName**
- The Trackbar is located in the window named **Linear Blend**
- The Trackbar values will be in the range from \f$0\f$ to **alpha_slider_max** (the minimum
@@ -51,10 +98,21 @@ We only analyze the code that is related to Trackbar:
- The numerical value of Trackbar is stored in **alpha_slider**
- Whenever the user moves the Trackbar, the callback function **on_trackbar** is called
-# Finally, we have to define the callback function **on_trackbar**
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp on_trackbar
Finally, we have to define the callback function **on_trackbar** for C++ and Python code, using an anonymous inner class listener in Java
Note that:
@add_toggle_cpp
@snippet cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp on_trackbar
@end_toggle
@add_toggle_java
@snippet java/tutorial_code/highgui/trackbar/AddingImagesTrackbar.java on_trackbar
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/highgui/trackbar/AddingImagesTrackbar.py on_trackbar
@end_toggle
Note that (C++ code):
- We use the value of **alpha_slider** (integer) to get a double value for **alpha**.
- **alpha_slider** is updated each time the trackbar is displaced by the user.
- We define *src1*, *src2*, *dist*, *alpha*, *alpha_slider* and *beta* as global variables,
@@ -11,9 +11,6 @@ In this tutorial you will learn how to:
- @ref cv::erode
- @ref cv::dilate
Interesting fact
-----------
@note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
Morphological Operations
@@ -38,19 +35,14 @@ Morphological Operations
- As the kernel \f$B\f$ is scanned over the image, we compute the maximal pixel value overlapped by
\f$B\f$ and replace the image pixel in the anchor point position with that maximal value. As you can
deduce, this maximizing operation causes bright regions within an image to "grow" (therefore the
name *dilation*). Take the above image as an example. Applying dilation we can get:
name *dilation*).
- The dilatation operation is: \f$\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f$
- Take the above image as an example. Applying dilation we can get:
![](images/Morphology_1_Tutorial_Theory_Dilation.png)
The background (bright) dilates around the black regions of the letter.
To better grasp the idea and avoid possible confusion, in this other example we have inverted the original
image such as the object in white is now the letter. We have performed two dilatations with a rectangular
structuring element of size `3x3`.
![Left image: original image inverted, right image: resulting dilatation](images/Morphology_1_Tutorial_Theory_Dilatation_2.png)
The dilatation makes the object in white bigger.
- The bright area of the letter dilates around the black regions of the background.
### Erosion
@@ -58,31 +50,39 @@ The dilatation makes the object in white bigger.
area of given kernel.
- As the kernel \f$B\f$ is scanned over the image, we compute the minimal pixel value overlapped by
\f$B\f$ and replace the image pixel under the anchor point with that minimal value.
- The erosion operation is: \f$\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f$
- Analagously to the example for dilation, we can apply the erosion operator to the original image
(shown above). You can see in the result below that the bright areas of the image (the
background, apparently), get thinner, whereas the dark zones (the "writing") gets bigger.
(shown above). You can see in the result below that the bright areas of the image get thinner,
whereas the dark zones gets bigger.
![](images/Morphology_1_Tutorial_Theory_Erosion.png)
In similar manner, the corresponding image results by applying erosion operation on the inverted original image (two erosions
with a rectangular structuring element of size `3x3`):
![Left image: original image inverted, right image: resulting erosion](images/Morphology_1_Tutorial_Theory_Erosion_2.png)
The erosion makes the object in white smaller.
Code
----
@add_toggle_cpp
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp)
@include samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp
@end_toggle
@add_toggle_java
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java)
@include samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java
@end_toggle
@add_toggle_python
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py)
@include samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py
@end_toggle
Explanation
-----------
-# Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in
previous sections). Let's check the general structure of the program:
previous sections). Let's check the general structure of the C++ program:
- Load an image (can be BGR or grayscale)
- Create two windows (one for dilation output, the other for erosion)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 B

After

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 B

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 685 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 617 B

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -36,15 +36,10 @@ discuss briefly 5 operations offered by OpenCV:
foreground)
- For instance, check out the example below. The image at the left is the original and the image
at the right is the result after applying the opening transformation. We can observe that the
small spaces in the corners of the letter tend to disappear.
small dots have disappeared.
![](images/Morphology_2_Tutorial_Theory_Opening.png)
For the sake of clarity, we have performed the opening operation (`7x7` rectangular structuring element)
on the same original image but inverted such as the object in white is now the letter.
![Left image: original image inverted, right image: resulting opening](images/Morphology_2_Tutorial_Theory_Opening_2.png)
### Closing
- It is obtained by the dilation of an image followed by an erosion.
@@ -55,10 +50,6 @@ on the same original image but inverted such as the object in white is now the l
![](images/Morphology_2_Tutorial_Theory_Closing.png)
On the inverted image, we have performed the closing operation (`7x7` rectangular structuring element):
![Left image: original image inverted, right image: resulting closing](images/Morphology_2_Tutorial_Theory_Closing_2.png)
### Morphological Gradient
- It is the difference between the dilation and the erosion of an image.
@@ -88,14 +79,28 @@ On the inverted image, we have performed the closing operation (`7x7` rectangula
Code
----
This tutorial code's is shown lines below. You can also download it from
@add_toggle_cpp
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp)
@include cpp/tutorial_code/ImgProc/Morphology_2.cpp
@end_toggle
@add_toggle_java
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java)
@include java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java
@end_toggle
@add_toggle_python
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py)
@include python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py
@end_toggle
Explanation
-----------
-# Let's check the general structure of the program:
-# Let's check the general structure of the C++ program:
- Load an image
- Create a window to display results of the Morphological operations
- Create three Trackbars for the user to enter parameters:
@@ -139,8 +144,8 @@ Explanation
Results
-------
- After compiling the code above we can execute it giving an image path as an argument. For this
tutorial we use as input the image: **baboon.png**:
- After compiling the code above we can execute it giving an image path as an argument. Results using
the image: **baboon.png**:
![](images/Morphology_2_Tutorial_Original_Image.jpg)