mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 11:40:44 +08:00
Merge pull request #17839 from malliaridis:master
This commit is contained in:
commit
87ed750510
@ -84,28 +84,35 @@ This tutorial's code is shown below. You can also download it
|
|||||||
Explanation
|
Explanation
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
-# Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in
|
@add_toggle_cpp
|
||||||
previous sections). Let's check the general structure of the C++ program:
|
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 C++ program:
|
||||||
|
|
||||||
- Load an image (can be BGR or grayscale)
|
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp main
|
||||||
- Create two windows (one for dilation output, the other for erosion)
|
|
||||||
- Create a set of two Trackbars for each operation:
|
-# Load an image (can be BGR or grayscale)
|
||||||
|
-# Create two windows (one for dilation output, the other for erosion)
|
||||||
|
-# Create a set of two Trackbars for each operation:
|
||||||
- The first trackbar "Element" returns either **erosion_elem** or **dilation_elem**
|
- The first trackbar "Element" returns either **erosion_elem** or **dilation_elem**
|
||||||
- The second trackbar "Kernel size" return **erosion_size** or **dilation_size** for the
|
- The second trackbar "Kernel size" return **erosion_size** or **dilation_size** for the
|
||||||
corresponding operation.
|
corresponding operation.
|
||||||
- Every time we move any slider, the user's function **Erosion** or **Dilation** will be
|
-# Call once erosion and dilation to show the initial image.
|
||||||
called and it will update the output image based on the current trackbar values.
|
|
||||||
|
|
||||||
Let's analyze these two functions:
|
|
||||||
|
|
||||||
-# **erosion:**
|
Every time we move any slider, the user's function **Erosion** or **Dilation** will be
|
||||||
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp erosion
|
called and it will update the output image based on the current trackbar values.
|
||||||
|
|
||||||
- The function that performs the *erosion* operation is @ref cv::erode . As we can see, it
|
Let's analyze these two functions:
|
||||||
receives three arguments:
|
|
||||||
- *src*: The source image
|
#### The erosion function
|
||||||
- *erosion_dst*: The output image
|
|
||||||
- *element*: This is the kernel we will use to perform the operation. If we do not
|
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp erosion
|
||||||
|
|
||||||
|
The function that performs the *erosion* operation is @ref cv::erode . As we can see, it
|
||||||
|
receives three arguments:
|
||||||
|
- *src*: The source image
|
||||||
|
- *erosion_dst*: The output image
|
||||||
|
- *element*: This is the kernel we will use to perform the operation. If we do not
|
||||||
specify, the default is a simple `3x3` matrix. Otherwise, we can specify its
|
specify, the default is a simple `3x3` matrix. Otherwise, we can specify its
|
||||||
shape. For this, we need to use the function cv::getStructuringElement :
|
shape. For this, we need to use the function cv::getStructuringElement :
|
||||||
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp kernel
|
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp kernel
|
||||||
@ -119,22 +126,156 @@ Explanation
|
|||||||
Then, we just have to specify the size of our kernel and the *anchor point*. If not
|
Then, we just have to specify the size of our kernel and the *anchor point*. If not
|
||||||
specified, it is assumed to be in the center.
|
specified, it is assumed to be in the center.
|
||||||
|
|
||||||
- That is all. We are ready to perform the erosion of our image.
|
That is all. We are ready to perform the erosion of our image.
|
||||||
@note Additionally, there is another parameter that allows you to perform multiple erosions
|
|
||||||
(iterations) at once. However, We haven't used it in this simple tutorial. You can check out the
|
|
||||||
reference for more details.
|
|
||||||
|
|
||||||
-# **dilation:**
|
#### The dilation function
|
||||||
|
|
||||||
The code is below. As you can see, it is completely similar to the snippet of code for **erosion**.
|
The code is below. As you can see, it is completely similar to the snippet of code for **erosion**.
|
||||||
Here we also have the option of defining our kernel, its anchor point and the size of the operator
|
Here we also have the option of defining our kernel, its anchor point and the size of the operator
|
||||||
to be used.
|
to be used.
|
||||||
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp dilation
|
@snippet cpp/tutorial_code/ImgProc/Morphology_1.cpp dilation
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
|
@add_toggle_java
|
||||||
|
Most of the material shown here is trivial (if you have any doubt, please refer to the tutorials in
|
||||||
|
previous sections). Let's check however the general structure of the java class. There are 4 main
|
||||||
|
parts in the java class:
|
||||||
|
|
||||||
|
- the class constructor which setups the window that will be filled with window components
|
||||||
|
- the `addComponentsToPane` method, which fills out the window
|
||||||
|
- the `update` method, which determines what happens when the user changes any value
|
||||||
|
- the `main` method, which is the entry point of the program
|
||||||
|
|
||||||
|
In this tutorial we will focus on the `addComponentsToPane` and `update` methods. However, for completion the
|
||||||
|
steps followed in the constructor are:
|
||||||
|
|
||||||
|
-# Load an image (can be BGR or grayscale)
|
||||||
|
-# Create a window
|
||||||
|
-# Add various control components with `addComponentsToPane`
|
||||||
|
-# show the window
|
||||||
|
|
||||||
|
The components were added by the following method:
|
||||||
|
|
||||||
|
@snippet java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java components
|
||||||
|
|
||||||
|
In short we
|
||||||
|
|
||||||
|
-# create a panel for the sliders
|
||||||
|
-# create a combo box for the element types
|
||||||
|
-# create a slider for the kernel size
|
||||||
|
-# create a combo box for the morphology function to use (erosion or dilation)
|
||||||
|
|
||||||
|
The action and state changed listeners added call at the end the `update` method which updates
|
||||||
|
the image based on the current slider values. So every time we move any slider, the `update` method is triggered.
|
||||||
|
|
||||||
|
#### Updating the image
|
||||||
|
|
||||||
|
To update the image we used the following implementation:
|
||||||
|
|
||||||
|
@snippet java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java update
|
||||||
|
|
||||||
|
In other words we
|
||||||
|
|
||||||
|
-# get the structuring element the user chose
|
||||||
|
-# execute the **erosion** or **dilation** function based on `doErosion`
|
||||||
|
-# reload the image with the morphology applied
|
||||||
|
-# repaint the frame
|
||||||
|
|
||||||
|
Let's analyze the `erode` and `dilate` methods:
|
||||||
|
|
||||||
|
#### The erosion method
|
||||||
|
|
||||||
|
@snippet java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java erosion
|
||||||
|
|
||||||
|
The function that performs the *erosion* operation is @ref cv::erode . As we can see, it
|
||||||
|
receives three arguments:
|
||||||
|
- *src*: The source image
|
||||||
|
- *erosion_dst*: The output image
|
||||||
|
- *element*: This is the kernel we will use to perform the operation. For specifying the shape, we need to use
|
||||||
|
the function cv::getStructuringElement :
|
||||||
|
@snippet java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java kernel
|
||||||
|
|
||||||
|
We can choose any of three shapes for our kernel:
|
||||||
|
|
||||||
|
- Rectangular box: CV_SHAPE_RECT
|
||||||
|
- Cross: CV_SHAPE_CROSS
|
||||||
|
- Ellipse: CV_SHAPE_ELLIPSE
|
||||||
|
|
||||||
|
Together with the shape we specify the size of our kernel and the *anchor point*. If the anchor point is not
|
||||||
|
specified, it is assumed to be in the center.
|
||||||
|
|
||||||
|
That is all. We are ready to perform the erosion of our image.
|
||||||
|
|
||||||
|
#### The dilation function
|
||||||
|
|
||||||
|
The code is below. As you can see, it is completely similar to the snippet of code for **erosion**.
|
||||||
|
Here we also have the option of defining our kernel, its anchor point and the size of the operator
|
||||||
|
to be used.
|
||||||
|
@snippet java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java dilation
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
|
@add_toggle_python
|
||||||
|
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 python script:
|
||||||
|
|
||||||
|
@snippet python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py main
|
||||||
|
|
||||||
|
-# Load an image (can be BGR or grayscale)
|
||||||
|
-# Create two windows (one for erosion output, the other for dilation) with a set of trackbars each
|
||||||
|
- The first trackbar "Element" returns the value for the morphological type that will be mapped
|
||||||
|
(1 = rectangle, 2 = cross, 3 = ellipse)
|
||||||
|
- The second trackbar "Kernel size" returns the size of the element for the
|
||||||
|
corresponding operation
|
||||||
|
-# Call once erosion and dilation to show the initial image
|
||||||
|
|
||||||
|
Every time we move any slider, the user's function **erosion** or **dilation** will be
|
||||||
|
called and it will update the output image based on the current trackbar values.
|
||||||
|
|
||||||
|
Let's analyze these two functions:
|
||||||
|
|
||||||
|
#### The erosion function
|
||||||
|
|
||||||
|
@snippet python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py erosion
|
||||||
|
|
||||||
|
The function that performs the *erosion* operation is @ref cv::erode . As we can see, it
|
||||||
|
receives two arguments and returns the processed image:
|
||||||
|
- *src*: The source image
|
||||||
|
- *element*: The kernel we will use to perform the operation. We can specify its
|
||||||
|
shape by using the function cv::getStructuringElement :
|
||||||
|
@snippet python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py kernel
|
||||||
|
|
||||||
|
We can choose any of three shapes for our kernel:
|
||||||
|
|
||||||
|
- Rectangular box: MORPH_RECT
|
||||||
|
- Cross: MORPH_CROSS
|
||||||
|
- Ellipse: MORPH_ELLIPSE
|
||||||
|
|
||||||
|
Then, we just have to specify the size of our kernel and the *anchor point*. If the anchor point not
|
||||||
|
specified, it is assumed to be in the center.
|
||||||
|
|
||||||
|
That is all. We are ready to perform the erosion of our image.
|
||||||
|
|
||||||
|
#### The dilation function
|
||||||
|
|
||||||
|
The code is below. As you can see, it is completely similar to the snippet of code for **erosion**.
|
||||||
|
Here we also have the option of defining our kernel, its anchor point and the size of the operator
|
||||||
|
to be used.
|
||||||
|
|
||||||
|
@snippet python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py dilation
|
||||||
|
@end_toggle
|
||||||
|
|
||||||
|
@note Additionally, there are further parameters that allow you to perform multiple erosions/dilations
|
||||||
|
(iterations) at once and also set the border type and value. However, We haven't used those
|
||||||
|
in this simple tutorial. You can check out the reference for more details.
|
||||||
|
|
||||||
Results
|
Results
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Compile the code above and execute it with an image as argument. For instance, using this image:
|
Compile the code above and execute it (or run the script if using python) with an image as argument.
|
||||||
|
If you do not provide an image as argument the default sample image
|
||||||
|
([LinuxLogo.jpg](https://github.com/opencv/opencv/tree/master/samples/data/LinuxLogo.jpg)) will be used.
|
||||||
|
|
||||||
|
For instance, using this image:
|
||||||
|
|
||||||
![](images/Morphology_1_Tutorial_Original_Image.jpg)
|
![](images/Morphology_1_Tutorial_Original_Image.jpg)
|
||||||
|
|
||||||
@ -143,3 +284,4 @@ naturally. Try them out! You can even try to add a third Trackbar to control the
|
|||||||
iterations.
|
iterations.
|
||||||
|
|
||||||
![](images/Morphology_1_Result.jpg)
|
![](images/Morphology_1_Result.jpg)
|
||||||
|
(depending on the programming language the output might vary a little or be only 1 window)
|
||||||
|
@ -25,6 +25,7 @@ int const max_kernel_size = 21;
|
|||||||
void Erosion( int, void* );
|
void Erosion( int, void* );
|
||||||
void Dilation( int, void* );
|
void Dilation( int, void* );
|
||||||
|
|
||||||
|
//![main]
|
||||||
/**
|
/**
|
||||||
* @function main
|
* @function main
|
||||||
*/
|
*/
|
||||||
@ -70,6 +71,7 @@ int main( int argc, char** argv )
|
|||||||
waitKey(0);
|
waitKey(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
//![main]
|
||||||
|
|
||||||
//![erosion]
|
//![erosion]
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,7 @@ public class MorphologyDemo1 {
|
|||||||
private JFrame frame;
|
private JFrame frame;
|
||||||
private JLabel imgLabel;
|
private JLabel imgLabel;
|
||||||
|
|
||||||
|
//! [constructor]
|
||||||
public MorphologyDemo1(String[] args) {
|
public MorphologyDemo1(String[] args) {
|
||||||
String imagePath = args.length > 0 ? args[0] : "../data/LinuxLogo.jpg";
|
String imagePath = args.length > 0 ? args[0] : "../data/LinuxLogo.jpg";
|
||||||
matImgSrc = Imgcodecs.imread(imagePath);
|
matImgSrc = Imgcodecs.imread(imagePath);
|
||||||
@ -54,7 +55,9 @@ public class MorphologyDemo1 {
|
|||||||
frame.pack();
|
frame.pack();
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
|
//! [constructor]
|
||||||
|
|
||||||
|
//! [components]
|
||||||
private void addComponentsToPane(Container pane, Image img) {
|
private void addComponentsToPane(Container pane, Image img) {
|
||||||
if (!(pane.getLayout() instanceof BorderLayout)) {
|
if (!(pane.getLayout() instanceof BorderLayout)) {
|
||||||
pane.add(new JLabel("Container doesn't use BorderLayout!"));
|
pane.add(new JLabel("Container doesn't use BorderLayout!"));
|
||||||
@ -114,21 +117,31 @@ public class MorphologyDemo1 {
|
|||||||
imgLabel = new JLabel(new ImageIcon(img));
|
imgLabel = new JLabel(new ImageIcon(img));
|
||||||
pane.add(imgLabel, BorderLayout.CENTER);
|
pane.add(imgLabel, BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
|
//! [components]
|
||||||
|
|
||||||
|
//! [update]
|
||||||
private void update() {
|
private void update() {
|
||||||
|
//! [kernel]
|
||||||
Mat element = Imgproc.getStructuringElement(elementType, new Size(2 * kernelSize + 1, 2 * kernelSize + 1),
|
Mat element = Imgproc.getStructuringElement(elementType, new Size(2 * kernelSize + 1, 2 * kernelSize + 1),
|
||||||
new Point(kernelSize, kernelSize));
|
new Point(kernelSize, kernelSize));
|
||||||
|
//! [kernel]
|
||||||
|
|
||||||
if (doErosion) {
|
if (doErosion) {
|
||||||
|
//! [erosion]
|
||||||
Imgproc.erode(matImgSrc, matImgDst, element);
|
Imgproc.erode(matImgSrc, matImgDst, element);
|
||||||
|
//! [erosion]
|
||||||
} else {
|
} else {
|
||||||
|
//! [dilation]
|
||||||
Imgproc.dilate(matImgSrc, matImgDst, element);
|
Imgproc.dilate(matImgSrc, matImgDst, element);
|
||||||
|
//! [dilation]
|
||||||
}
|
}
|
||||||
Image img = HighGui.toBufferedImage(matImgDst);
|
Image img = HighGui.toBufferedImage(matImgDst);
|
||||||
imgLabel.setIcon(new ImageIcon(img));
|
imgLabel.setIcon(new ImageIcon(img));
|
||||||
frame.repaint();
|
frame.repaint();
|
||||||
}
|
}
|
||||||
|
//! [update]
|
||||||
|
|
||||||
|
//! [main]
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Load the native OpenCV library
|
// Load the native OpenCV library
|
||||||
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||||
@ -142,4 +155,5 @@ public class MorphologyDemo1 {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//! [main]
|
||||||
}
|
}
|
||||||
|
@ -3,61 +3,76 @@ import cv2 as cv
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
src = None
|
||||||
erosion_size = 0
|
erosion_size = 0
|
||||||
max_elem = 2
|
max_elem = 2
|
||||||
max_kernel_size = 21
|
max_kernel_size = 21
|
||||||
title_trackbar_element_type = 'Element:\n 0: Rect \n 1: Cross \n 2: Ellipse'
|
title_trackbar_element_shape = 'Element:\n 0: Rect \n 1: Cross \n 2: Ellipse'
|
||||||
title_trackbar_kernel_size = 'Kernel size:\n 2n +1'
|
title_trackbar_kernel_size = 'Kernel size:\n 2n +1'
|
||||||
title_erosion_window = 'Erosion Demo'
|
title_erosion_window = 'Erosion Demo'
|
||||||
title_dilatation_window = 'Dilation Demo'
|
title_dilation_window = 'Dilation Demo'
|
||||||
|
|
||||||
def erosion(val):
|
|
||||||
erosion_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_erosion_window)
|
|
||||||
erosion_type = 0
|
|
||||||
val_type = cv.getTrackbarPos(title_trackbar_element_type, title_erosion_window)
|
|
||||||
if val_type == 0:
|
|
||||||
erosion_type = cv.MORPH_RECT
|
|
||||||
elif val_type == 1:
|
|
||||||
erosion_type = cv.MORPH_CROSS
|
|
||||||
elif val_type == 2:
|
|
||||||
erosion_type = cv.MORPH_ELLIPSE
|
|
||||||
|
|
||||||
element = cv.getStructuringElement(erosion_type, (2*erosion_size + 1, 2*erosion_size+1), (erosion_size, erosion_size))
|
## [main]
|
||||||
erosion_dst = cv.erode(src, element)
|
def main(image):
|
||||||
cv.imshow(title_erosion_window, erosion_dst)
|
global src
|
||||||
|
src = cv.imread(cv.samples.findFile(image))
|
||||||
def dilatation(val):
|
if src is None:
|
||||||
dilatation_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_dilatation_window)
|
print('Could not open or find the image: ', image)
|
||||||
dilatation_type = 0
|
|
||||||
val_type = cv.getTrackbarPos(title_trackbar_element_type, title_dilatation_window)
|
|
||||||
if val_type == 0:
|
|
||||||
dilatation_type = cv.MORPH_RECT
|
|
||||||
elif val_type == 1:
|
|
||||||
dilatation_type = cv.MORPH_CROSS
|
|
||||||
elif val_type == 2:
|
|
||||||
dilatation_type = cv.MORPH_ELLIPSE
|
|
||||||
|
|
||||||
element = cv.getStructuringElement(dilatation_type, (2*dilatation_size + 1, 2*dilatation_size+1), (dilatation_size, dilatation_size))
|
|
||||||
dilatation_dst = cv.dilate(src, element)
|
|
||||||
cv.imshow(title_dilatation_window, dilatation_dst)
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Code for Eroding and Dilating tutorial.')
|
|
||||||
parser.add_argument('--input', help='Path to input image.', default='LinuxLogo.jpg')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
src = cv.imread(cv.samples.findFile(args.input))
|
|
||||||
if src is None:
|
|
||||||
print('Could not open or find the image: ', args.input)
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
cv.namedWindow(title_erosion_window)
|
cv.namedWindow(title_erosion_window)
|
||||||
cv.createTrackbar(title_trackbar_element_type, title_erosion_window , 0, max_elem, erosion)
|
cv.createTrackbar(title_trackbar_element_shape, title_erosion_window, 0, max_elem, erosion)
|
||||||
cv.createTrackbar(title_trackbar_kernel_size, title_erosion_window , 0, max_kernel_size, erosion)
|
cv.createTrackbar(title_trackbar_kernel_size, title_erosion_window, 0, max_kernel_size, erosion)
|
||||||
|
|
||||||
cv.namedWindow(title_dilatation_window)
|
cv.namedWindow(title_dilation_window)
|
||||||
cv.createTrackbar(title_trackbar_element_type, title_dilatation_window , 0, max_elem, dilatation)
|
cv.createTrackbar(title_trackbar_element_shape, title_dilation_window, 0, max_elem, dilatation)
|
||||||
cv.createTrackbar(title_trackbar_kernel_size, title_dilatation_window , 0, max_kernel_size, dilatation)
|
cv.createTrackbar(title_trackbar_kernel_size, title_dilation_window, 0, max_kernel_size, dilatation)
|
||||||
|
|
||||||
erosion(0)
|
erosion(0)
|
||||||
dilatation(0)
|
dilatation(0)
|
||||||
cv.waitKey()
|
cv.waitKey()
|
||||||
|
## [main]
|
||||||
|
|
||||||
|
# optional mapping of values with morphological shapes
|
||||||
|
def morph_shape(val):
|
||||||
|
if val == 0:
|
||||||
|
return cv.MORPH_RECT
|
||||||
|
elif val == 1:
|
||||||
|
return cv.MORPH_CROSS
|
||||||
|
elif val == 2:
|
||||||
|
return cv.MORPH_ELLIPSE
|
||||||
|
|
||||||
|
|
||||||
|
## [erosion]
|
||||||
|
def erosion(val):
|
||||||
|
erosion_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_erosion_window)
|
||||||
|
erosion_shape = morph_shape(cv.getTrackbarPos(title_trackbar_element_shape, title_erosion_window))
|
||||||
|
|
||||||
|
## [kernel]
|
||||||
|
element = cv.getStructuringElement(erosion_shape, (2 * erosion_size + 1, 2 * erosion_size + 1),
|
||||||
|
(erosion_size, erosion_size))
|
||||||
|
## [kernel]
|
||||||
|
erosion_dst = cv.erode(src, element)
|
||||||
|
cv.imshow(title_erosion_window, erosion_dst)
|
||||||
|
## [erosion]
|
||||||
|
|
||||||
|
|
||||||
|
## [dilation]
|
||||||
|
def dilatation(val):
|
||||||
|
dilatation_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_dilation_window)
|
||||||
|
dilation_shape = morph_shape(cv.getTrackbarPos(title_trackbar_element_shape, title_dilation_window))
|
||||||
|
|
||||||
|
element = cv.getStructuringElement(dilation_shape, (2 * dilatation_size + 1, 2 * dilatation_size + 1),
|
||||||
|
(dilatation_size, dilatation_size))
|
||||||
|
dilatation_dst = cv.dilate(src, element)
|
||||||
|
cv.imshow(title_dilation_window, dilatation_dst)
|
||||||
|
## [dilation]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description='Code for Eroding and Dilating tutorial.')
|
||||||
|
parser.add_argument('--input', help='Path to input image.', default='LinuxLogo.jpg')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
main(args.input)
|
||||||
|
Loading…
Reference in New Issue
Block a user