From 27867cc72c94637f240ebc7f39a448295f7d2b9f Mon Sep 17 00:00:00 2001 From: krikera Date: Fri, 27 Jun 2025 21:09:53 +0530 Subject: [PATCH] Add MORPH_DIAMOND support to samples and tutorials --- .../js_morphological_ops/js_morphological_ops.markdown | 2 +- .../py_morphological_ops/py_morphological_ops.markdown | 8 ++++++++ .../erosion_dilatation/erosion_dilatation.markdown | 2 ++ samples/cpp/morphology2.cpp | 7 +++++-- samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp | 8 +++++--- samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp | 4 ++-- samples/gpu/morphology.cpp | 9 +++++++-- .../ImgProc/erosion_dilatation/MorphologyDemo1.java | 4 +++- samples/python/morphology.py | 2 +- .../imgProc/erosion_dilatation/morphology_1.py | 6 ++++-- .../imgProc/opening_closing_hats/morphology_2.py | 6 ++++-- 11 files changed, 42 insertions(+), 16 deletions(-) diff --git a/doc/js_tutorials/js_imgproc/js_morphological_ops/js_morphological_ops.markdown b/doc/js_tutorials/js_imgproc/js_morphological_ops/js_morphological_ops.markdown index 9ffa218bb2..09cad1003c 100644 --- a/doc/js_tutorials/js_imgproc/js_morphological_ops/js_morphological_ops.markdown +++ b/doc/js_tutorials/js_imgproc/js_morphological_ops/js_morphological_ops.markdown @@ -158,7 +158,7 @@ Structuring Element ------------------- We manually created a structuring elements in the previous examples with help of cv.Mat.ones. It is -rectangular shape. But in some cases, you may need elliptical/circular shaped kernels. So for this +rectangular shape. But in some cases, you may need elliptical/circular shaped kernels or diamond-shaped kernels. So for this purpose, OpenCV has a function, **cv.getStructuringElement()**. You just pass the shape and size of the kernel, you get the desired kernel. diff --git a/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.markdown b/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.markdown index 24b504914f..6d56d26095 100644 --- a/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.markdown +++ b/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.markdown @@ -147,6 +147,14 @@ array([[0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]], dtype=uint8) + +# Diamond-shaped Kernel +>>> cv.getStructuringElement(cv.MORPH_DIAMOND,(5,5)) +array([[0, 0, 1, 0, 0], + [0, 1, 1, 1, 0], + [1, 1, 1, 1, 1], + [0, 1, 1, 1, 0], + [0, 0, 1, 0, 0]], dtype=uint8) @endcode Additional Resources -------------------- diff --git a/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown b/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown index 36829683d5..2ba3061bab 100644 --- a/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown +++ b/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.markdown @@ -129,6 +129,7 @@ receives three arguments: - Rectangular box: MORPH_RECT - Cross: MORPH_CROSS - Ellipse: MORPH_ELLIPSE + - Diamond: MORPH_DIAMOND 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. @@ -256,6 +257,7 @@ receives two arguments and returns the processed image: - Rectangular box: MORPH_RECT - Cross: MORPH_CROSS - Ellipse: MORPH_ELLIPSE + - Diamond: MORPH_DIAMOND 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. diff --git a/samples/cpp/morphology2.cpp b/samples/cpp/morphology2.cpp index f1d8d15b17..e6bb659cac 100644 --- a/samples/cpp/morphology2.cpp +++ b/samples/cpp/morphology2.cpp @@ -12,12 +12,13 @@ static void help(char** argv) printf("\nShow off image morphology: erosion, dialation, open and close\n" "Call:\n %s [image]\n" - "This program also shows use of rect, ellipse and cross kernels\n\n", argv[0]); + "This program also shows use of rect, ellipse, cross and diamond kernels\n\n", argv[0]); printf( "Hot keys: \n" "\tESC - quit the program\n" "\tr - use rectangle structuring element\n" "\te - use elliptic structuring element\n" "\tc - use cross-shaped structuring element\n" + "\td - use diamond-shaped structuring element\n" "\tSPACE - loop through all the options\n" ); } @@ -101,8 +102,10 @@ int main( int argc, char** argv ) element_shape = MORPH_RECT; else if( c == 'c' ) element_shape = MORPH_CROSS; + else if( c == 'd' ) + element_shape = MORPH_DIAMOND; else if( c == ' ' ) - element_shape = (element_shape + 1) % 3; + element_shape = (element_shape + 1) % 4; } return 0; diff --git a/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp b/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp index 33e006269d..6c30ff34ac 100644 --- a/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp @@ -18,7 +18,7 @@ int erosion_elem = 0; int erosion_size = 0; int dilation_elem = 0; int dilation_size = 0; -int const max_elem = 2; +int const max_elem = 3; int const max_kernel_size = 21; /** Function Headers */ @@ -47,7 +47,7 @@ int main( int argc, char** argv ) moveWindow( "Dilation Demo", src.cols, 0 ); /// Create Erosion Trackbar - createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo", + createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse \n 3: Diamond", "Erosion Demo", &erosion_elem, max_elem, Erosion ); @@ -56,7 +56,7 @@ int main( int argc, char** argv ) Erosion ); /// Create Dilation Trackbar - createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo", + createTrackbar( "Element:\n 0: Rect \n 1: Cross \n 2: Ellipse \n 3: Diamond", "Dilation Demo", &dilation_elem, max_elem, Dilation ); @@ -83,6 +83,7 @@ void Erosion( int, void* ) if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; } else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; } else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; } + else if( erosion_elem == 3) { erosion_type = MORPH_DIAMOND; } //![kernel] Mat element = getStructuringElement( erosion_type, @@ -106,6 +107,7 @@ void Dilation( int, void* ) if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; } else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; } else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; } + else if( dilation_elem == 3) { dilation_type = MORPH_DIAMOND; } Mat element = getStructuringElement( dilation_type, Size( 2*dilation_size + 1, 2*dilation_size+1 ), diff --git a/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp b/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp index 3bc40d3b0d..bab4489b7e 100644 --- a/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp @@ -18,7 +18,7 @@ int morph_elem = 0; int morph_size = 0; int morph_operator = 0; int const max_operator = 4; -int const max_elem = 2; +int const max_elem = 3; int const max_kernel_size = 21; const char* window_name = "Morphology Transformations Demo"; @@ -54,7 +54,7 @@ int main( int argc, char** argv ) //![create_trackbar2] /// Create Trackbar to select kernel type - createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name, + createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse - 3: Diamond", window_name, &morph_elem, max_elem, Morphology_Operations ); //![create_trackbar2] diff --git a/samples/gpu/morphology.cpp b/samples/gpu/morphology.cpp index b5e50caa3c..0ace6ddced 100644 --- a/samples/gpu/morphology.cpp +++ b/samples/gpu/morphology.cpp @@ -101,8 +101,12 @@ int App::run() element_shape = MORPH_CROSS; break; + case 'd': + element_shape = MORPH_DIAMOND; + break; + case ' ': - element_shape = (element_shape + 1) % 3; + element_shape = (element_shape + 1) % 4; break; } } @@ -113,13 +117,14 @@ void App::help() cout << "Show off image morphology: erosion, dialation, open and close \n"; cout << "Call: \n"; cout << " gpu-example-morphology [image] \n"; - cout << "This program also shows use of rect, ellipse and cross kernels \n" << endl; + cout << "This program also shows use of rect, ellipse, cross and diamond kernels \n" << endl; cout << "Hot keys: \n"; cout << "\tESC - quit the program \n"; cout << "\tr - use rectangle structuring element \n"; cout << "\te - use elliptic structuring element \n"; cout << "\tc - use cross-shaped structuring element \n"; + cout << "\td - use diamond-shaped structuring element \n"; cout << "\tSPACE - loop through all the options \n" << endl; } diff --git a/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java b/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java index 084fc9544d..8f11965995 100644 --- a/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java +++ b/samples/java/tutorial_code/ImgProc/erosion_dilatation/MorphologyDemo1.java @@ -23,7 +23,7 @@ import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; public class MorphologyDemo1 { - private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse" }; + private static final String[] ELEMENT_TYPE = { "Rectangle", "Cross", "Ellipse", "Diamond" }; private static final String[] MORPH_OP = { "Erosion", "Dilatation" }; private static final int MAX_KERNEL_SIZE = 21; private Mat matImgSrc; @@ -79,6 +79,8 @@ public class MorphologyDemo1 { elementType = Imgproc.MORPH_CROSS; } else if (cb.getSelectedIndex() == 2) { elementType = Imgproc.MORPH_ELLIPSE; + } else if (cb.getSelectedIndex() == 3) { + elementType = Imgproc.MORPH_DIAMOND; } update(); } diff --git a/samples/python/morphology.py b/samples/python/morphology.py index 183f5e8288..f816e4916d 100755 --- a/samples/python/morphology.py +++ b/samples/python/morphology.py @@ -40,7 +40,7 @@ def main(): cv.imshow('original', img) modes = cycle(['erode/dilate', 'open/close', 'blackhat/tophat', 'gradient']) - str_modes = cycle(['ellipse', 'rect', 'cross']) + str_modes = cycle(['ellipse', 'rect', 'cross', 'diamond']) if PY3: cur_mode = next(modes) diff --git a/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py b/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py index 3645eab3d1..21b404ef46 100644 --- a/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py +++ b/samples/python/tutorial_code/imgProc/erosion_dilatation/morphology_1.py @@ -5,9 +5,9 @@ import argparse src = None erosion_size = 0 -max_elem = 2 +max_elem = 3 max_kernel_size = 21 -title_trackbar_element_shape = 'Element:\n 0: Rect \n 1: Cross \n 2: Ellipse' +title_trackbar_element_shape = 'Element:\n 0: Rect \n 1: Cross \n 2: Ellipse \n 3: Diamond' title_trackbar_kernel_size = 'Kernel size:\n 2n +1' title_erosion_window = 'Erosion Demo' title_dilation_window = 'Dilation Demo' @@ -42,6 +42,8 @@ def morph_shape(val): return cv.MORPH_CROSS elif val == 2: return cv.MORPH_ELLIPSE + elif val == 3: + return cv.MORPH_DIAMOND ## [erosion] diff --git a/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py b/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py index e0fc758467..667fa50a30 100644 --- a/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py +++ b/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py @@ -5,10 +5,10 @@ import argparse morph_size = 0 max_operator = 4 -max_elem = 2 +max_elem = 3 max_kernel_size = 21 title_trackbar_operator_type = 'Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat' -title_trackbar_element_type = 'Element:\n 0: Rect - 1: Cross - 2: Ellipse' +title_trackbar_element_type = 'Element:\n 0: Rect - 1: Cross - 2: Ellipse - 3: Diamond' title_trackbar_kernel_size = 'Kernel size:\n 2n + 1' title_window = 'Morphology Transformations Demo' morph_op_dic = {0: cv.MORPH_OPEN, 1: cv.MORPH_CLOSE, 2: cv.MORPH_GRADIENT, 3: cv.MORPH_TOPHAT, 4: cv.MORPH_BLACKHAT} @@ -24,6 +24,8 @@ def morphology_operations(val): morph_elem = cv.MORPH_CROSS elif val_type == 2: morph_elem = cv.MORPH_ELLIPSE + elif val_type == 3: + morph_elem = cv.MORPH_DIAMOND element = cv.getStructuringElement(morph_elem, (2*morph_size + 1, 2*morph_size+1), (morph_size, morph_size)) operation = morph_op_dic[morph_operator]