[PYTHON] Horizon processing using OpenCV morphology transformation

I think there are various ways to process horizon etc. in image processing, Let's think about horizon processing etc. using OpenCV morphology conversion in python. Morphological transformation generally refers to processes such as expansion and contraction. Let's specify an extreme kernel (structural element) for this. It's a kind of trick.

About processing

Image processing is performed as follows.

  1. Binarize
  2. Generate (n x 1) kernel (structural element) For horizon processing (50x1), (100x1) ... Make it like this For vertical line processing (1x8), (1x10) ... Make it like this
  3. Erosion in the generated kernel
  4. Delay with the generated kernel

About the kernel (structural element)

The kernel (structural element) is generated as follows.

10x1 kernel(Structural elements)For horizon extraction


>>> cv2.getStructuringElement(cv2.MORPH_RECT,(20,1))
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
      dtype=uint8)

1x10 kernel(Structural elements)For vertical line extraction


>>> cv2.getStructuringElement(cv2.MORPH_RECT, (1,10))
array([[1],
       [1],
       [1],
       [1],
       [1],
       [1],
       [1],
       [1],
       [1],
       [1]], dtype=uint8)

By the way, general expansion and contraction are also listed.

Usually rectangular kernel(Structural elements)


>>> cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]], dtype=uint8)

About morphology transformation

horizontal = cv2.erode(horizontal, hKernel)
horizontal = cv2.dilate(horizontal, hKernel)

The erosion is performed after the erosion is executed.

Input image

Delta.png

See how horizontal lines are processed.

program

morph_delta.py


import numpy as np
import cv2
import sys

#Image display
def showImage(winname, img):
    cv2.imshow(winname, img)
    cv2.moveWindow(winname, 500, 0)
    cv2.waitKey(0)
    cv2.destroyWindow(winname)

def main(imagefile):
    #image load
    src = cv2.imread(imagefile,cv2.IMREAD_GRAYSCALE)
    if src is None:
        print ('Error image: ' + imagefile)
        return -1

    #Invert and binarize
    gray = cv2.bitwise_not(src)
    binimage = cv2.adaptiveThreshold(gray, 255, 
        cv2.ADAPTIVE_THRESH_MEAN_C, 
        cv2.THRESH_BINARY, 15, -2)
    #Binarized display
    showImage("BINARIZE", binimage)
    for hv in range(50, 301, 50):
        morphHorizontalLine(binimage, hv)
    for vv in range(2, 17, 2):
        morphVerticalLine(binimage, vv)
    return  0


#Morphology transformation Extract horizontal lines
# hor_size Extract horizontal line
#Morphology transformation structural element parameters
def morphHorizontalLine(binimage, hor_size):
    horizontal = np.copy(binimage)

    #Horizon by morphology calculation
    #Generate structural elements for extraction.
    hKernel = cv2.getStructuringElement(cv2.MORPH_RECT,
                        (hor_size, 1))

    #Extract horizontal lines by morphology calculation
    horizontal = cv2.erode(horizontal, hKernel)
    horizontal = cv2.dilate(horizontal, hKernel)

    cap = 'hor_size=%d' % (hor_size)
    cv2.putText(horizontal, cap, (10,25), 
        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255), 1,cv2.LINE_AA)

    #Horizon image display
    showImage("HORIZONTAL LINES", horizontal)

#Morphology transformation Extract vertical lines
# ver_size Extract vertical lines
#Morphology transformation structural element parameters
def morphVerticalLine(binimage, ver_size):
    vertical = np.copy(binimage)

    #Vertical lines by morphology calculation
    #Generate structural elements for extraction.
    hKernel = cv2.getStructuringElement(cv2.MORPH_RECT,
                        (1,ver_size))

    #Extract horizontal lines by morphology calculation
    vertical = cv2.erode(vertical, hKernel)
    vertical = cv2.dilate(vertical, hKernel)

    cap = 'ver_size=%d' % (ver_size)
    cv2.putText(vertical, cap, (10,25), 
        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255), 1,cv2.LINE_AA)

    #Horizon image display
    showImage("VERTICAL LINES", vertical)

if __name__ == "__main__":
    main('image/Delta.png')

Development environment

Windows10 Anaconda python 3.7.6 OpenCV 3.4.1

Execution result

Horizon extraction

20200118_result.jpg hor_size = 50 is processed by (50,1) kernel (structural element). hor_size = 100 executes up to (100,1), (300,1).

The vertical line and the short horizontal line at the top disappear.

Vertical line extraction

20200118_vresult.jpg

ver_size = 2 is processed by (1,2) kernel (structural element). ver_size = 6 is executed as (1,6), (1,8). The horizontal line has disappeared. good feeling.

application

Now that we know the movement of morphology transformation, we can apply the staff to the score I will try to process it. By the way, the score is "Gunkan March" which seems to be booming. The beginning is excerpted.

Warship_march_score2.png

Advanced program

morph_lines.py


import numpy as np
import cv2
import sys

#Image display
def showImage(winname, img):
	cv2.imshow(winname, img)
	cv2.moveWindow(winname, 500, 0)
	cv2.waitKey(0)
	cv2.destroyWindow(winname)

def	main(imagefile):
	#image load
	src = cv2.imread(imagefile, cv2.IMREAD_GRAYSCALE)
	if src is None:
		print ('Error image: ' + imagefile)
	return -1

	#Invert and binarize
	gray = cv2.bitwise_not(src)
	binimage = cv2.adaptiveThreshold(gray, 255, 
		cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, -2)
	#Binarized display
	showImage("BINARIZE", binimage)
	morphLine(binimage, 5)
	return	0

#Morphology transformation
# ver_size Extract horizontal line Morphology transformation structural element parameter
def	morphLine(binimage, ver_size):
	#Image buffer generation for horizontal line extraction
	vertical = np.copy(binimage)

	#Generate structural elements for extracting vertical lines by morphology operations.
	vKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, ver_size))

	#Extract vertical lines by morphology calculation
	vertical = cv2.erode(vertical, vKernel)
	vertical = cv2.dilate(vertical, vKernel)

	#Display vertical line image
	showImage("VERTICAL LINES", vertical)

	#	1)Extract edges
	#	2)Expansion dilate(contour_edge)
	#	3)Smoothing smooth
	#	4)Merge vertical line image and edge

	#Extract contour edges and smooth the image
	contour_edge = cv2.adaptiveThreshold(vertical, 255, 
		cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 3, -2)
	showImage("CONTOUR EDGE", contour_edge)

	#Edge image expansion
	kernel = np.ones((2, 2), np.uint8)
	contour_edge = cv2.dilate(contour_edge, kernel)
	showImage("DILATE contour_edge", contour_edge)

	#Image blur(Smoothing)
	#Normalized box filter to average
	smooth = cv2.blur(np.copy(vertical), (2, 2))

	#Merge vertical line image and edge
	#Coordinate extraction for the part where the edge exists
	#Overwrite the vertical image from the edge from the extracted coordinates
	(height, width) = np.where(contour_edge != 0)
	vertical[height, width] = smooth[height, width]

	#Result image display
	showImage("RESULT IMAGE", vertical)

if __name__ == "__main__":
	main('image/Warship_march_score.png')

I am running in a 5x1 kernel (structural element). The back side of the process is the restoration process to get the appearance of the image. Since it is not the essence in particular, the explanation is omitted.

Application version Execution result

ResultLine_v5.png

Is it such a place? About the place that says "I can do this" by changing the kernel (structural element) It's not a big deal in terms of content, but there are things that can be done with it There was something I felt and I wrote it down.

reference

Morphology Transformation — OpenCV-Python Tutorials 1 documentation opencv.org - Extract horizontal and vertical lines by using morphological operations Maritime Self-Defense Force Tokyo Music Corps JMSDF BAND, TOKYO --March "Gunkan"

Recommended Posts

Horizon processing using OpenCV morphology transformation
[Python] Using OpenCV with Python (Image transformation)
Video processing using Python + OpenCV on Mac
"Apple processing" with OpenCV3 + Python3
Feature detection using opencv (corner detection)
[Python] Using OpenCV with Python (Basic)
Try using OpenCV on Windows
Affine transformation by OpenCV (CUDA)
Gamma correction without using OpenCV
Implement reversi reversi processing using BitBoard
Using Python mode in Processing
Using OpenCV with Python @Mac
[Image processing] Edge detection using Python and OpenCV makes Poo naked!