Morphology - hit-miss transformation

Table of contents

1. Introduction to HMT

2. Code implementation


1. Introduction to HMT

The full name of HMT is Hit miss transformation --- Hit miss transformation. Here we only process binary images.

A binary image is an image with only two grayscale values , that is, an image that is either black or white. Therefore, 0 represents black and 255 represents white to represent a binary image.

HMT is a basic tool for shape detection, and its mathematical formula is:

  • Perform erosion operation on the foreground target (point with gray value 1255) through structural element B1
  • Use structural element B2 to perform erosion operations on the background target (point with a grayscale value of 0). Because we only process binary images, which only include foreground + background, the background target can also be considered as the complement of the foreground target.
  • Finally, find the common set of the images in the first two steps, that is, the intersection

The above are all concepts in the book. Let me talk about my understanding below:

The word hit-miss actually contains two meanings: hit, miss

A hit is equivalent to the first step in the book, a miss is equivalent to the second step in the book, and the final intersection is the hit-miss transformation.

  • What is a hit? We can analogize SE to the form of a spatial filter. For example, the kernel of (3, 3) slides on the image. If the point on the kernel corresponds to the point on the image, it is a hit, so before the center of the kernel is output Attractions. This process is corrosion
  • Why miss? Similarly, the background is operated through another kernel. Note that we are operating on the background here. If the background is hit, the foreground point is output. Because we operate on the background, if we hit the background, it can be equivalent to not hitting the foreground.

But two kernels are needed here, and the kernels need to be different (otherwise there will be no intersection). In addition, the complement of the image needs to be calculated, etc. The process is very troublesome. We can use a kernel similar to spatial filtering. Directly implement the hit-miss transformation

Because the kernel needs to contain two parts, hit and miss, the kernel needs two values ​​corresponding to hit and miss respectively. And often there are some positions on our kernel that we don't care about, which means that the corresponding position doesn't care whether it is the foreground or the background, so another value is needed.

Therefore, the hit-miss transformation kernel contains three values, which we define as follows:

  • 1 means hit
  • -1 means miss
  • 0 represents a point of no interest

As shown in the picture:

 We process the image through five different SEs: Here, for the convenience of viewing, the pixel values ​​of the binary image are inverted. But it’s not important, we just need to remember that black is the foreground of interest and white is the background of no interest.

By observing SE, we can see that there are no uninteresting points here, that is, SE has only two values.

For example, in the first one, the place we are interested in is the target in a circle around (3, 3), and the center point is the background point that we are not interested in. So we draw a conclusion: when the kernel filters the original image, we only output the foreground point when the original image satisfies a background point surrounded by a circle of foreground points . When the surrounding points are satisfied, we call it a hit; when the center point is also satisfied, the satisfaction here actually represents the complement that satisfies the original image, that is, the complement hits and the original image fails.

Therefore, we can draw a conclusion that  the original image needs to completely match the SE before the foreground point will be output (the complete match here is the point of -1 and 1, and 0 represents the uninteresting point)

2. Code implementation

As shown in the picture:

We now extract the main contours of this image. 

The code is:

import cv2
import numpy as np

img = cv2.imread('./img.png',0)
ret , img = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)   # 阈值处理
img = cv2.resize(img,None,fx = 0.5,fy = 0.5)    # 缩小图像

kernel_horizontal = np.array([[0,-1,0],[0,1,0],[0,0,0]])   # 横着的 kernel
dst_horizontal = cv2.morphologyEx(img,cv2.MORPH_HITMISS,kernel_horizontal)

kernel_vertical = np.array([[0,0,0],[-1,1,0],[0,0,0]])   # 竖着的 kernel
dst_vertical = cv2.morphologyEx(img,cv2.MORPH_HITMISS,kernel_vertical)

dst = cv2.add(dst_horizontal,dst_vertical)
cv2.imshow('img',np.hstack((img,dst_horizontal,dst_vertical,dst)))
cv2.waitKey()
cv2.destroyAllWindows()

process result:

  •  It can be seen from observation that if you want to find a horizontal line, you only need to satisfy that the center point is the hit point 1, and the above pixel point is the missed point -1. That is to say, the original image needs to ensure that the white pixels are immediately above the black ones. of pixels can be output
  • The middle column is not written as (transpose of [-1,1,-1]) because there is no guarantee that the straight line of the image is a single pixel wide.
  • Especially when looking at circles, you can find that the arc above the horizontal diameter passing through the origin has output because the tangent of the horizontal diameter circle is exactly vertical.

If there is no -1 in the kernel, that is, if the feature cannot be hit, the result is actually corrosion.

おすすめ

転載: blog.csdn.net/qq_44886601/article/details/127545171#comments_27947686