Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV: How to correctly apply morphologyEx operation?

Tags:

python

opencv

I am having a problem regarding the kernel size for morphologyEx. I have some captcha images and I want to do the same operation on them and get the same final result.

code :

image = cv2.imread("Image.jpg")
gray = cv2.cvtColor(image , cv2.COLOR_BGR2GRAY)


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

k1 = np.ones((3,3))
k2 = np.ones((5,5))
bottom_image = cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, k1)
bottom_image =  255-bottom_image
bottom_image = remove_boxes(bottom_image , True)


ret,thresh2 = cv2.threshold(bottom_image,127,255,cv2.THRESH_BINARY_INV)
opening = cv2.morphologyEx(thresh2, cv2.MORPH_OPEN, k1)


#closing =  cv2.morphologyEx(opening, cv2.MORPH_CLOSE, k)
# cv2.imshow('opening', opening)

dilate = cv2.morphologyEx(opening, cv2.MORPH_DILATE, k2)
dilate = cv2.bitwise_not(dilate)
# cv2.imshow('dilation', dilate)


bottom_image = cv2.morphologyEx(bottom_image, cv2.MORPH_CLOSE, k1)

The perfect result would be

Input:
enter image description here

Output:
enter image description here

But the problem appears when I apply it to other images with the same structure output is distorted.

Example 1 :

Input:
enter image description here

Output:
enter image description here

Example 2 :

Input:
enter image description here

Output:
enter image description here

Example 3:

Input:
enter image description here

Output:
enter image description here

like image 492
ahmed osama Avatar asked Jun 24 '18 10:06

ahmed osama


People also ask

What is morphologyEx in OpenCV?

The morphologyEx() of the method of the class Imgproc is used to perform these operations on a given image. Following is the syntax of this method − morphologyEx(src, dst, op, kernel) This method accepts the following parameters − src − An object of the class Mat representing the source (input) image.

What is erosion and dilation in OpenCV?

Erosion and Dilation are morphological image processing operations. OpenCV morphological image processing is a procedure for modifying the geometric structure in the image. In morphism, we find the shape and size or structure of an object.

What does CV dilate do?

As the kernel B is scanned over the image, we compute the maximal pixel value overlapped by B 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).

What is morphological transformation in image processing?

Morphology is a broad set of image processing operations that process images based on shapes. Morphological operations apply a structuring element to an input image, creating an output image of the same size.


1 Answers

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()

1

2

3

4

like image 154
zindarod Avatar answered Sep 28 '22 19:09

zindarod