🌐
coseries
coseries.com › morphological-transformations-in-python-using-opencv
Morphological Transformations in Python using OpenCV | coseries
November 22, 2020 - Consider the example below. import cv2 img = cv2.imread("morph2.png", 0) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9)) top_hat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) cv2.imshow("Original image", img) cv2.imshow("Top Hat", ...
🌐
ProgramCreek
programcreek.com › python › example › 89381 › cv2.getStructuringElement
Python Examples of cv2.getStructuringElement
def __init__(self, min_accuracy, min_blend_area, kernel_fill=20, dist_threshold=15000, history=400): self.min_accuracy = max (min_accuracy, 0.7) self.min_blend_area = min_blend_area self.kernel_clean = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(4,4)) self.kernel_fill = np.ones((kernel_fill,kernel_fill),np.uint8) self.dist_threshold = dist_threshold self.history = history # read https://docs.opencv.org/3.3.0/d2/d55/group__bgsegm.html#gae561c9701970d0e6b35ec12bae149814 try: self.fgbg = cv2.bgsegm.createBackgroundSubtractorMOG(history=self.history, nmixtures=5, backgroundRatio=0.7, noiseSigma=0) except AttributeError as error: print ('It looks like your OpenCV version does not include bgsegm.
🌐
OpenCV-Python Tutorials
opencv24-python-tutorials.readthedocs.io › en › latest › py_tutorials › py_imgproc › py_morphological_ops › py_morphological_ops.html
Morphological Transformations — OpenCV-Python Tutorials beta documentation
# Rectangular Kernel >>> cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]], dtype=uint8) # Elliptical Kernel >>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) array([[0, 0, 1, 0, 0], [1, 1, 1, 1, ...
🌐
OpenCV
docs.opencv.org › 4.x › dd › dd7 › tutorial_morph_lines_detection.html
OpenCV: Extract horizontal and vertical lines by using morphological operations
Mat horizontalStructure = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(horizontal_size,1)); // Apply morphology operations · Imgproc.erode(horizontal, horizontal, horizontalStructure); Imgproc.dilate(horizontal, horizontal, horizontalStructure); // Show extracted horizontal lines · showWaitDestroy("horizontal" , horizontal); Python ·
🌐
Python Geeks
pythongeeks.org › python geeks › learn opencv › morphological operations in opencv
Morphological Operations in OpenCV - Python Geeks
February 14, 2023 - # Importing OpenCV import cv2 # Importing numpy import numpy as np # Reading the image img = cv2.imread(r"C:\Users\tushi\Downloads\PythonGeeks\butterfly with gaps.jpg", 0) # Displaying the original image cv2.imshow('Original',img) cv2.waitKey(0) cv2.destroyAllWindows() # Defining the kernel kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) # Printing the kernel kernel # Output array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]], dtype=uint8) # Applying the structuring element with the rectangle shape on the image img_rect = cv2.morphologyEx(img, cv2.MORPH_RECT, kernel) # Displaying the image cv2.imshow('Rectangle',img_rect) cv2.waitKey(0) cv2.destroyAllWindows()
🌐
OpenCV
docs.opencv.org › 3.4 › d4 › d76 › tutorial_js_morphological_ops.html
OpenCV: Morphological Transformations
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 purpose, OpenCV has a function, cv.getStructuringElement().
🌐
Medium
mamuncseru.medium.com › a-brief-discussion-on-morphological-operators-using-opencv-ccf6be076896
A brief discussion on Morphological operators using OpenCV | by Md. Abdullah Al Mamun | Medium
January 20, 2023 - morph_rect = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(5, 5)) morph_ellipse = cv2.getStructuringElement(shape=cv2.MORPH_ELLIPSE, ksize=(5, 5)) morph_cross = cv2.getStructuringElement(shape=cv2.MORPH_CROSS, ksize=(5, 5)) Figure: ...
🌐
PyImageSearch
pyimagesearch.com › home › blog › opencv morphological operations
OpenCV Morphological Operations - PyImageSearch
May 9, 2021 - This is just an example of two simple structuring elements. But we could also make them arbitrary rectangle or circular structures as well — it all depends on your particular application. In OpenCV, we can either use the cv2.getStructuringElement function or NumPy itself to define our structuring element.
🌐
OpenCV
docs.opencv.org › 3.4.20 › d3 › dbe › tutorial_opening_closing_hats.html
OpenCV: More Morphology Transformations
element = cv.getStructuringElement(morph_elem, (2*morph_size + 1, 2*morph_size+1), (morph_size, morph_size))
Find elsewhere
🌐
O'Reilly
oreilly.com › library › view › mastering-opencv-4 › 9781789344912 › 01422dee-f186-4817-a960-87f293732bc2.xhtml
Structuring element - Mastering OpenCV 4 with Python [Book]
March 29, 2019 - Structuring element In connection with the structuring element, OpenCV provides the cv2.getStructuringElement() function. This function outputs the desired kernel (a NumPy array of... - Selection from Mastering OpenCV 4 with Python [Book]
Author   Alberto Fernández Villán
Published   2019
Pages   532
🌐
Shimat
shimat.github.io › opencvsharp_docs › html › a83a9f62-e3dc-c3e9-36bd-1758462d2198.htm
Cv2.GetStructuringElement Method (MorphShapes, Size)
Returns a structuring element of the specified size and shape for morphological operations. The function constructs and returns the structuring element that can be further passed to erode, dilate or morphologyEx.
🌐
Regenerativetoday
regenerativetoday.com › morphological-operations-for-image-preprocessing-in-opencv-in-detail
Morphological Operations for Image Preprocessing in OpenCV, in Detail – Regenerative
image = cv2.imread('car.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (23, 5)) kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (35, 8))
🌐
Blogger
opencvexamples.blogspot.com › 2013 › 10 › create-structuring-element-for.html
Learn OpenCV by Examples: Create structuring element for morphological operations
#include "opencv2/highgui/highgui.hpp" ... (SE) int morph_size = 3; Mat element = getStructuringElement( MORPH_ELLIPSE, Size( 4*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) ); cout<<element; return 0; } ...
Top answer
1 of 1
3

My first piece of advice is to not threshold right away. Thresholding is something you want to do way at the end. Thresholding throws away valuable information. Morphological operations work on grey-value images too!

Choosing the right morphological operators to keep only the shapes you are interested in is actually quite intuitive. In this case, you want to keep both horizontal and vertical lines. Let's use line structuring elements. The lines are dark, so we use a closing to remove things that do not look like our lines.

A closing with vertical lines will remove all horizontal lines, and a closing with horizontal lines will remove all vertical lines. So how to combine these two? It turns out that the infimum (pixel-wise minimum) of two closings is a closing also. So the infimum of a closing with vertical lines and one with horizontal lines is a closing with the two lines at the same time, you'll preserve shapes where either of those two lines fit.

Here is an example. I'm using PyDIP (I don't have OpenCV).

import diplib as dip
img = dip.ImageRead('/Users/cris/Downloads/ZrF7k.tif')
img = img.TensorElement(1) # keep only green channel
img = img[0:-2,1:-1]       # let's remove the artifacts at the right and top edges
f1 = dip.Closing(img, dip.SE([50,1],'rectangular'))
f2 = dip.Closing(img, dip.SE([1,50],'rectangular'))
out = dip.Infimum(f1, f2)
out.Show('lin')

You can try to tweak that a bit, and add some additional processing, and add your adaptive thresholding at the end to get the edges of the PV cells. But there is actually a much better way of finding these.

I'm taking advantage here of the fact that the panel is so very straight w.r.t. the image, and that it covers the whole image. We can simply take a mean projection along rows and along columns:

x = dip.Mean(out, process=[1, 0]).Squeeze()
y = dip.Mean(out, process=[0, 1]).Squeeze()
import matplotlib.pyplot as pp
pp.subplot(2,1,1)
pp.plot(x)
pp.subplot(2,1,2)
pp.plot(y)
pp.show()

It should be fairly straight-forward to detect the edges of the cells from these projections.

Top answer
1 of 2
1

This answer explains how to use MORPH_CLOSE around the edge of an image by adding a buffer to the image.

You can add a buffer by creating an image of zeros using numpy:

# Import packages
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Read in the image
img = cv2.imread('/home/stephen/Desktop/OKoUh.png', 0)
# Create a black bufffer around the image
h,w = img.shape
buffer = max(h,w)
bg = np.zeros((h+buffer*2, w+buffer*2), np.uint8)
bg[buffer:buffer+h, buffer:buffer+w] = img

Then you can iterate and check how it looks at different kernel sizes:

for close_size in range(1,11):
    temp  = bg.copy()
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (close_size, close_size))
    result = cv2.morphologyEx(temp, cv2.MORPH_CLOSE, kernel)
    results = result[buffer:buffer+h, buffer:buffer+w]
    cv2.imshow('img', result)
    cv2.waitKey()

My results:

2 of 2
1

Based on Stephen's answer, here is the snippet I ended up implementing :

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (close_size, close_size))
# Padding
im=cv2.copyMakeBorder(im,close_size,close_size,close_size,close_size,
                      borderType=cv2.BORDER_CONSTANT, value = 0)
# Closing
im = cv2.morphologyEx(im, cv2.MORPH_CLOSE, kernel)
# Unpadding
im = im[close_size:-close_size,close_size:-close_size]

As I mentionned in a comment, this can lead to a much longer computation time for large kernel sizes. It's possible that padding with lower values, eg close_size/2 would be enough to prevent border issues (didn't test it).

🌐
OpenCV
docs.opencv.org › 3.4.20 › db › df6 › tutorial_erosion_dilatation.html
OpenCV: Eroding and Dilating
You can see in the result below that the bright areas of the image get thinner, whereas the dark zones gets bigger. ... This tutorial's code is shown below. You can also download it here ... This tutorial's code is shown below. You can also download it here ... Mat element = Imgproc.getStruc...
🌐
Kaggle
kaggle.com › code › mukeshmanral › morphological-operations-opencv
Morphological Operations(OpenCV) | Kaggle
November 1, 2022 - Explore and run AI code with Kaggle Notebooks | Using data from [Private Datasource]
🌐
OpenCV
docs.opencv.org › 4.x › js_morphological_ops_getStructuringElement.html
Get Structuring Element Example
Get Structuring Element Example · <canvas> elements named canvasInput and canvasOutput have been prepared. Click Try it button to see the result. You can choose another image. You can change the code in the <textarea> to investigate more · Try it
🌐
Microsoft Learn
learn.microsoft.com › en-us › answers › questions › 433806 › preprocessing-an-array-of-python-images-opencv-c
Preprocessing an array of Python images OpenCV C++ - Microsoft Q&A
#include <iostream> #include <boost/python.hpp> #include <omp.h> #include <opencv4/opencv2/imgproc.hpp> #include <opencv4/opencv2/opencv.hpp> #include <boost/python/numpy.hpp> #include <numpy/arrayobject.h> using namespace cv; namespace py = boost::python; namespace np = boost::python::numpy; #define WIDTH 2048 #define HEIGHT 2896 void bold_preprocess(PyObject* args, PyObject* res_1) { cv::Size newImageSize, source_ImageSize; Mat img_resized; Py_Initialize(); import_array(); npy_intp shape [2] = {WIDTH, HEIGHT}; Mat MORPH_RECT_KERNEL = getStructuringElement(MORPH_RECT, Size(6, 6), Point(-1,-1)