[Reprinted] Open and close operations of the OpenCV-Python series (21)

The corrosion and expansion of the image is the core of this tutorial-the basis of the opening and closing operations. If the structure element is circular, the expansion operation can fill in the holes in the image that are smaller than the structure element and the small recesses at the edges of the image. Corrosion can eliminate burrs and small connection components in the image, and shrink the image, thereby expanding its complement. However, expansion and corrosion are not mutually inverse operations, so they can be used in combination. On the basis of the two basic operations of erosion and expansion, a morphological operation cluster can be constructed, which consists of all operations composed of the combination of expansion and erosion operations and set operations (union, intersection, complement, etc.). For example, you can use the same structural element to first corrode the image and then expand the result, which is called an open operation; or expand the image first and then corrode the result, which is called a closed operation. Open operation and close operation are the two most important operations in the morphological operation family.
For the image X and the structural element S, the symbol is used to indicate that S performs an open operation on the image X, and the symbol is used to indicate that S performs a closed operation on the image X. They are defined as:
Insert picture description here

First need to understand a function:

cv2.morphologyEx(src, op, kernel)

Parameter Description:

src incoming picture

How the op changes

kernel represents the size and shape of the defined convolution kernel

op = cv2.MORPH_OPEN to open operation, which means to perform corrosion operation first, and then perform expansion operation

op = cv2.MORPH_CLOSE to perform a closed operation, which refers to the expansion operation first, and then the corrosion operation

Open operation

The open operation refers to the first corrosion operation on the image, and then the expansion operation. Normally, it operates on the bright area of ​​the image to eliminate the white noise in the image. Now let’s look at the example. An image:
Insert picture description here

Now we want to eliminate the black burr in the image, but it is not possible to directly perform the opening operation on the image, because the opening operation is to operate on the bright area of ​​the image. See what effect the opening operation directly has:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
open =cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("result", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

As you can see, the burr of the image has not been removed. Now we need to threshold the original image, that is, reverse the black and white, so as to facilitate the morphological processing. We have talked about the threshold in the previous section, but we will not talk about it here. , Look at the code directly:

	view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
cv2.imshow("img",img)  
cv2.imshow("thres",threshold)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

Now that the image has been reversed from black and white, we can start the opening operation. Of course, we also need to define a convolution kernel. This has been discussed in the previous tutorial. Here we define a 3*3 rectangular volume. Product core:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("thres",threshold)  
cv2.imshow("result", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

This effect is obvious, if we change the convolution kernel to 5*5:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))  
open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)  
cv2.imshow("thres",threshold)  
cv2.imshow("result", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows() 

Insert picture description here

This shows that the operation is excessive, so the proper selection of the convolution kernel for morphological processing is very important. Now we restore the processed image:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('open.jpg',0)  
threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)  
result = cv2.threshold(open,0,255,cv2.THRESH_BINARY_INV|  
                          cv2.THRESH_OTSU)[1]  
cv2.imshow("img",img)  
cv2.imshow("thres",threshold)  
cv2.imshow("open", open)  
cv2.imshow("result",result)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Look at the result of the final restoration:
Insert picture description here

In fact, the flexible use of the convolution kernel will greatly facilitate the morphological processing of the image. Let's carry out a practical battle. For example, now give an image:
Insert picture description here

We will use the open operation to extract the horizontal and vertical lines respectively. We use the 13*1 convolution kernel to experiment:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('hengshu.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(13,1))  
open =cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

Isn’t it amazing? Now we use the 1*13 convolution kernel to experiment:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('hengshu.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,13))  
open =cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

The vertical line has also been perfectly extracted. In the actual combat of future projects, we will use this knowledge to filter out the redundant information in the image reasonably. In fact, we also found that the processed image is dark and there is no The original image is so bright, which can be handled in the top hat-black hat operation in the next tutorial.

Closed operation

We have been tossing about the opening operation for a long time. Now let’s play with the closing operation. The closing operation is the opposite of the opening operation. It expands and then corrodes. It is usually used to remove the noise in the bright area of ​​the image. Let's look at an image:
Insert picture description here

Now we are going to use the closing operation to remove the black points inside the bright area of ​​the image, and define a 7*7 convolution kernel. Let's look at the code:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('close.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))  
open =cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

As you can see, the effect is very good. Now let's carry out another experiment with practical significance. First look at the picture:
Insert picture description here

We need to extract the outlines of these characters and mark them with boxes. Each line of words is marked with a box. Of course, this involves the outline extraction and outline approximation that will be explained later, but here we will conduct an experiment first. If we want to mark each line of words with a box, then the first condition that needs to be met is that the words of each line must be connected together to form a whole, so that OpenCV can be used to extract their overall outline and then calibrate it. But now we see that these words are independent, they are not connected together, this time we can use closed operations. Let's look at the code:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
  
img = cv2.imread('text1.jpg',0)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(21,5))  
open =cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)  
cv2.imshow("img",img)  
cv2.imshow("open", open)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

In this way, all the fonts are connected together, which also facilitates the later contour extraction.

I give the comprehensive code here, you can play with it:

view plaincopy to clipboardprint?
import cv2  
import numpy as np  
  
img = cv2.imread('text1.jpg')  
test = img.copy()  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 5))  
close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)  
contour, _ = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  
cv2.drawContours(test, contour, -1, (0, 0, 255), 2)  
for c in contour:  
    x, y, w, h = cv2.boundingRect(c)  
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)  
cv2.imshow("result", img)  
cv2.imshow("test",test)  
cv2.imshow("close", close)  
cv2.waitKey(0)  
cv2.destroyAllWindows()  

Insert picture description here

The first picture is to extract the contour of the image, and the second is to extract the circumscribed rectangle of the contour. Is it interesting? This will be discussed slowly in the future.

Closed operations are generally used to deal with internal noise conditions, and open operations are used to deal with external noise conditions, so it is very important to use them reasonably.

Check the article summary page https://blog.csdn.net/weixin_44237705/article/details/107864965
More openvino technical information can be exchanged in the group~
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_44237705/article/details/108334759