This answer was inspired by this excellent post.

import numpy as np
import cv2

if __name__ == '__main__':

    image = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    ret,binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)

    binary = cv2.bitwise_not(binary)

    H = cv2.Sobel(binary, cv2.CV_8U, 0, 2)
    V = cv2.Sobel(binary, cv2.CV_8U, 2, 0)

    rows,cols = image.shape[:2]

    _,contours,_ = cv2.findContours(V, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        (x,y,w,h) = cv2.boundingRect(cnt)
        # rows/3 is the threshold for length of line
        if h > rows/3:
            cv2.drawContours(V, [cnt], -1, 255, -1)
            cv2.drawContours(binary, [cnt], -1, 255, -1)
        else:
            cv2.drawContours(V, [cnt], -1, 0, -1)

    _,contours,_ = cv2.findContours(H, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        (x,y,w,h) = cv2.boundingRect(cnt)
        # cols/3 is the threshold for length of line
        if w > cols/3:
            cv2.drawContours(H, [cnt], -1, 255, -1)
            cv2.drawContours(binary, [cnt], -1, 255, -1)
        else:
            cv2.drawContours(H, [cnt], -1, 0, -1)

    kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(3,3))
    H = cv2.morphologyEx(H, cv2.MORPH_DILATE, kernel,iterations = 3)
    V = cv2.morphologyEx(V, cv2.MORPH_DILATE, kernel, iterations = 3)

    cross = cv2.bitwise_and(H, V)

    _,contours,_ = cv2.findContours(cross,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    centroids = []
    for cnt in contours:
        mom = cv2.moments(cnt)
        (x,y) = mom['m10']/mom['m00'], mom['m01']/mom['m00']
        cv2.circle(image,(int(x),int(y)),4,(0,255,0),-1)
        centroids.append((x,y))

    centroids.sort(key = lambda x: x[0], reverse = False)
    centroids.sort(key = lambda x: x[1], reverse = False)

    dx = int(centroids[1][0] - centroids[0][0])
    centroids = np.array(centroids, dtype = np.float32)
    (x,y,w,h) = cv2.boundingRect(centroids)

    if x-dx > -5: x = max(x-dx,0)
    if h+dx <= rows+5: h = min(h+dx,rows)
    if w+dx <= cols+5: w = min(w+dx,cols)
    cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0))

    roi = binary[y:y+h,x:x+w]

    roi = cv2.morphologyEx(roi, cv2.MORPH_OPEN, kernel,iterations = 1)

    cv2.imshow('image', image)
    cv2.imshow('roi', roi)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Answer from zindarod on Stack Overflow
🌐
ProgramCreek
programcreek.com › python › example › 89318 › cv2.morphologyEx
Python Examples of cv2.morphologyEx
def predict0(): Vnet3d = Vnet3dModule(256, 256, 64, inference=True, model_path="model\\Vnet3dModule.pd") for filenumber in range(30): batch_xs = np.zeros(shape=(64, 256, 256)) for index in range(64): imgs = cv2.imread( "D:\Data\PROMISE2012\Vnet3d_data\\test\image\\" + str(filenumber) + "\\" + str(index) + ".bmp", 0) batch_xs[index, :, :] = imgs[128:384, 128:384] predictvalue = Vnet3d.prediction(batch_xs) for index in range(64): result = np.zeros(shape=(512, 512), dtype=np.uint8) result[128:384, 128:384] = predictvalue[index] kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) result = cv2.morphologyEx(result, cv2.MORPH_CLOSE, kernel) cv2.imwrite( "D:\Data\PROMISE2012\Vnet3d_data\\test\image\\" + str(filenumber) + "\\" + str(index) + "mask.bmp", result)
Top answer
1 of 1
8

This answer was inspired by this excellent post.

import numpy as np
import cv2

if __name__ == '__main__':

    image = cv2.imread('image.png',cv2.IMREAD_UNCHANGED)

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    ret,binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)

    binary = cv2.bitwise_not(binary)

    H = cv2.Sobel(binary, cv2.CV_8U, 0, 2)
    V = cv2.Sobel(binary, cv2.CV_8U, 2, 0)

    rows,cols = image.shape[:2]

    _,contours,_ = cv2.findContours(V, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        (x,y,w,h) = cv2.boundingRect(cnt)
        # rows/3 is the threshold for length of line
        if h > rows/3:
            cv2.drawContours(V, [cnt], -1, 255, -1)
            cv2.drawContours(binary, [cnt], -1, 255, -1)
        else:
            cv2.drawContours(V, [cnt], -1, 0, -1)

    _,contours,_ = cv2.findContours(H, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        (x,y,w,h) = cv2.boundingRect(cnt)
        # cols/3 is the threshold for length of line
        if w > cols/3:
            cv2.drawContours(H, [cnt], -1, 255, -1)
            cv2.drawContours(binary, [cnt], -1, 255, -1)
        else:
            cv2.drawContours(H, [cnt], -1, 0, -1)

    kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(3,3))
    H = cv2.morphologyEx(H, cv2.MORPH_DILATE, kernel,iterations = 3)
    V = cv2.morphologyEx(V, cv2.MORPH_DILATE, kernel, iterations = 3)

    cross = cv2.bitwise_and(H, V)

    _,contours,_ = cv2.findContours(cross,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    centroids = []
    for cnt in contours:
        mom = cv2.moments(cnt)
        (x,y) = mom['m10']/mom['m00'], mom['m01']/mom['m00']
        cv2.circle(image,(int(x),int(y)),4,(0,255,0),-1)
        centroids.append((x,y))

    centroids.sort(key = lambda x: x[0], reverse = False)
    centroids.sort(key = lambda x: x[1], reverse = False)

    dx = int(centroids[1][0] - centroids[0][0])
    centroids = np.array(centroids, dtype = np.float32)
    (x,y,w,h) = cv2.boundingRect(centroids)

    if x-dx > -5: x = max(x-dx,0)
    if h+dx <= rows+5: h = min(h+dx,rows)
    if w+dx <= cols+5: w = min(w+dx,cols)
    cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0))

    roi = binary[y:y+h,x:x+w]

    roi = cv2.morphologyEx(roi, cv2.MORPH_OPEN, kernel,iterations = 1)

    cv2.imshow('image', image)
    cv2.imshow('roi', roi)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

🌐
PyTutorial
pytutorial.com › python-opencv-cv2morphologyex-guide
PyTutorial | Python OpenCV cv2.morphologyEx() Guide
January 16, 2025 - Learn how to use Python OpenCV cv2.morphologyEx() for advanced image processing. Includes examples, code, and explanations for beginners.
🌐
Python Programming
pythonprogramming.net › morphological-transformation-python-opencv-tutorial
Morphological Transformations OpenCV Python Tutorial
cap = cv2.VideoCapture(1) while(1): _, frame = cap.read() hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_red = np.array([30,150,50]) upper_red = np.array([255,255,180]) mask = cv2.inRange(hsv, lower_red, upper_red) res = cv2.bitwise_and(frame,frame, mask= mask) kernel = np.ones((5,5),np.uint8) opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) cv2.imshow('Original',frame) cv2.imshow('Mask',mask) cv2.imshow('Opening',opening) cv2.imshow('Closing',closing) k = cv2.waitKey(5) & 0xFF if k == 27: break cv2.destroyAllWindows() cap.release()
🌐
OpenCV
docs.opencv.org › 4.13.0 › d9 › d61 › tutorial_py_morphological_ops.html
OpenCV: Morphological Transformations
gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel) ... It is the difference between input image and Opening of the image. Below example is done for a 9x9 kernel.
🌐
TheAILearner
theailearner.com › tag › cv2-morphologyex
cv2.morphologyEx – TheAILearner
July 31, 2019 - If it matches exactly then the pixel underneath the origin of SE is set to 1 else 0. Let’s take an example. Suppose we want to find the above combined SE in the image shown below. Clearly, the one on the lower right matches the pattern defined by the combined SE. The result is shown on the right side. Below is the code for this. The hit-or-miss can be implemented using the OpenCV cv2.morphologyEx() function by passing the flag cv2.MORPH_HITMISS as shown below.
🌐
GeeksforGeeks
geeksforgeeks.org › python-opencv-morphological-operations
Python OpenCV - Morphological Operations - GeeksforGeeks
January 3, 2023 - Then we can make use of the Opencv cv.morphologyEx() function to perform an Opening operation on the image. Python3 ·
🌐
EDUCBA
educba.com › home › software development › software development tutorials › programming languages tutorial › opencv morphology
OpenCV Morphology | How to work Morphology function in OpenCV?
April 18, 2023 - We make use of the operation MORPH_OPEN in morphologyEx() function to perform opening morphological operations on a given image.
Address   Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
Find elsewhere
🌐
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\dots.jpg", 0) # Displaying the image cv2.imshow('Original',img) cv2.waitKey(0) cv2.destroyAllWindows() # Defining the kernel kernel = np.ones((5,5),np.uint8) # Apply the opening morphological operation using cv2.morphologyEx() function img_opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # Displaying the image after the opening morphological operation cv2.imshow('Opening',img_opening) cv2.waitKey(0) cv2.destroyAllWindows()
🌐
Master Data Science
datahacker.rs › 006-morphological-transformations-with-opencv-in-python
#006 Morphological transformations with OpenCV in Python
August 15, 2020 - # Performing opening and closing opening_1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel_1) opening_2 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel_2) opening_3 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel_3) closing_1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel_1) closing_2 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel_2) closing_3 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel_3) titles=["opening_1","opening_2","opening_3","closing_1","closing_2", "closing_3"] images=[ opening_1, opening_2, opening_3, closing_1, closing_2, closing_3] for i in range(6): plt.subplot(2, 3, i+1), plt.imshow(images[i], "gray") plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show ... In the following example you can see the difference between the original image and all of the processed images.
🌐
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 - white_noise = (np.random.randint(low=0, high=2, size=binary_img.shape) * 255)\ .astype('uint8') binary_with_noise_img = binary_img + white_noise opening_img = cv2.morphologyEx(binary_with_noise_img, cv2.MORPH_OPEN,\ morph_cross) plt.imshow(opening_img)
🌐
PyImageSearch
pyimagesearch.com › home › blog › opencv morphological operations
OpenCV Morphological Operations - PyImageSearch
May 9, 2021 - The first required argument of cv2.morphologyEx is the image we want to apply the morphological operation to. The second argument is the actual type of morphological operation — in this case, it’s an opening operation.
🌐
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", ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-morphological-operations-in-image-processing-opening-set-1
Python | Morphological Operations in Image Processing (Opening) | Set-1 - GeeksforGeeks
August 11, 2025 - import cv2 import numpy as np # Start capturing from webcam screenRead = cv2.VideoCapture(0) while True: # Capture a single frame from the webcam _, image = screenRead.read() # Convert to HSV color space hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # Define blue color range blue1 = np.array([110, 50, 50]) blue2 = np.array([130, 255, 255]) # Create binary mask for blue color mask = cv2.inRange(hsv, blue1, blue2) # Define 5x5 structuring element (kernel) kernel = np.ones((5, 5), np.uint8) # Apply Opening to remove small white noise opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) # Show both original mask and cleaned version cv2.imshow('Original Blue Mask', mask) cv2.imshow('After Opening (Noise Removed)', opening) # Press 'a' key to stop if cv2.waitKey(1) & 0xFF == ord('a'): break # Clean up cv2.destroyAllWindows() screenRead.release()
🌐
TutorialsPoint
tutorialspoint.com › opencv › opencv_morphological_operations.htm
OpenCV - Morphological Operations
import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; public class MorphologyExTest { public static void main(String args[]) { // Loading the OpenCV core library System.loadLibrary( Core.NATIVE_LIBRARY_NAME ); // Reading the Image from the file and storing it in to a Matrix object String file ="E:/OpenCV/chap12/morph_input.jpg"; Mat src = Imgcodecs.imread(file); // Creating an empty matrix to store the result Mat dst = new Mat(); // Creating kernel matrix Mat kernel = Mat.ones(5,5, CvTyp
🌐
Regenerativetoday
regenerativetoday.com › morphological-operations-for-image-preprocessing-in-opencv-in-detail
Morphological Operations for Image Preprocessing in OpenCV, in Detail – Regenerative
grad1 = cv2.morphologyEx(gray.copy(), cv2.MORPH_GRADIENT, kernel) cv2.imwrite('grad1.jpg', grad1) grad2 = cv2.morphologyEx(gray.copy(), cv2.MORPH_GRADIENT, kernel1) cv2.imwrite(‘grad3.jpg’, grad2)
🌐
Meganano
meganano.uno › opencv-morphological-operations
OpenCV: Morphological Operations – Meganano
May 8, 2023 - In OpenCV, these morphological operations can be performed using functions like cv2.dilate(), cv2.erode(), cv2.morphologyEx(), and so on. These functions allow you to specify the kernel or structuring element, control the size and shape of the neighborhood, and adjust the iterations to achieve the desired effect. Note that morphological operations are typically applied to binary or grayscale images where the objects of interest are represented by different intensity values or color regions. Let’s go through a basic Python example using erosion and dilation, two fundamental morphological operations.
🌐
TutorialsPoint
tutorialspoint.com › how-to-compute-the-morphological-gradient-of-an-image-using-opencv-in-python
How to compute the morphological gradient of an image using OpenCV in Python?
import cv2 import numpy as np img = cv2.imread('tutorialspoint.png',0) kernel1 = np.ones((2,2),np.uint8) gradient1 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel1) kernel2 = np.ones((3,3),np.uint8) gradient2 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel2) kernel3 = np.ones((5,5),np.uint8) gradient3 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel3) cv2.imshow("Morphological Gradient kernel= 2x2", gradient1) cv2.imshow("Morphological Gradient kernel= 3x3", gradient2) cv2.imshow("Morphological Gradient kernel= 5x5", gradient3) cv2.waitKey(0) cv2.destroyAllWindows()