一、边界跟踪法
- 边界跟踪
定义为从图像中的一个边界点出发,然后根据某种判别准则搜索出下一个边界点,以此跟踪出目标边界。
二、边界跟踪的一般步骤
- 如下:
- 1)确定边界的起始搜索点,起始点的选择很关键,对于某些图像,选择不同的起始点会导致不同的结果.
- 2)确定合适边界判别准则和搜索准则,判别准则主要用于判断一个点是不是边界点,搜索准则则知道如何搜索下一个边缘点。
- 3)确定搜索的终止条件。
三、 算法原理
边界跟踪示意图,图中黑点表示边界点,白点为图像的内部点- 跟踪的初始点是最左下方的黑点(即最后一行的最左黑点),跟踪的初始方向设定为左上角45度。
- 跟踪开始后,初始点沿初始跟踪方向检测该方向是否有黑点(检测距离为一个像素点),如果是,则保存初始点,将检测到的点作为新的初始点,同时在原来检测的基础上,逆时针旋转90度作为新的跟踪方向。如果不是目标点,则沿顺时针旋转45度,沿新跟踪方向继续检测,直到找到黑色像素,然后将跟踪方向逆时针旋转90作为新的跟踪方向。
- 重复上面不断改变跟踪方向,直到找到新的边界点。找到新的边界点后,将旧的边界点保存,将新检测到的点作为新的初始点。
- 这样不断重复上述过程,直到检测点回到最开始的检测点为止。
注意:中心像素可以跟踪的方向有8个,对每个方向制定了方向编号以及偏移量,如下图所示。一般来说,通常选取图像的最左下角的像素点作为起点。
四、程序
import cv2
import numpy as np
# 图像二值化
def get_binary_img(img):
# gray img to bin image
bin_img = np.zeros(img.shape,np.uint8)
h = img.shape[0]
w = img.shape[1]
for i in range(h):
for j in range(w):
bin_img[i][j] = 255 if img[i][j] > 200 else 0
return bin_img
# 边界跟踪, 从左上角查找开始
def get_left_up_start_pt(bin_img):
h = bin_img.shape[0]
w = bin_img.shape[1]
find = 0
start_i = 0
start_j = 0
for i in range(h):
for j in range(w):
if bin_img[i][j] == 0:
find = 1
start_i = i
start_j = j
break
return find,start_i,start_j
def trace_contour(bin_img,find,start_i,start_j):
contour_img = np.zeros(shape=(bin_img.shape), dtype=np.uint8)
contour_img += 255
if find:
contour_img[start_i][start_j] = 0
Direct = [(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0)]
BeginDirect = 0
findstart = 0
cur_i = start_i
cur_j = start_j
while findstart==0 :
findpoint = 0
while findpoint==0:
i = cur_i + Direct[BeginDirect][1]
j = cur_j + Direct[BeginDirect][0]
pixel = bin_img[i][j]
if pixel==0:
findpoint = 1
cur_i = i
cur_j = j
if cur_i ==start_i and cur_j == start_j:
findstart = 1
contour_img[cur_i][cur_j] = 0
BeginDirect-=1
if BeginDirect == -1:
BeginDirect = 7
BeginDirect-=1
if BeginDirect == -1:
BeginDirect = 7
else:
BeginDirect += 1
if BeginDirect == 8:
BeginDirect = 0
return contour_img
img = cv2.imread("d:\\Cup.jpg")
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
bin_img = get_binary_img(gray_img)
find, start_i, start_j = get_left_up_start_pt(bin_img)
contour_img = trace_contour(bin_img,find,start_i,start_j)
cv2.imshow("img",img)
cv2.imshow("gray_img",gray_img)
cv2.imshow("bin_img",bin_img)
cv2.imshow("contour_img",contour_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
五、资料
赵卓不凡的博客:《目标轮廓提取之边界跟踪法》
https://blog.csdn.net/sgzqc/article/details/119631617
网友评论