📅  最后修改于: 2023-12-03 15:13:07.885000             🧑  作者: Mango
2D线的链码是一种用来表示二维空间内连续的线条的编码方式。它将每个像素点与它相邻的像素点连接起来,形成连续的线条,然后通过数字编码对这些连续线条进行描述。
算法的输入是一个二维的图片数组,输出为一串数字,表示该图片的线条。
从图片中任选一点作为起点,顺时针扫描周围的8个像素点,找到第一个非白色像素点并记录下该点的坐标和编号。
用该点坐标替换当前点坐标,并将该点的编号存储,重复步骤1,直到回到起点点。
对每个连通图(由多条连续线条组成)进行同样的编码。
对于多个连通图,将它们的编码按顺序连接起来,作为最终的编码结果。
代码实现的具体细节会因不同的编程语言而有所不同,下面给出一个 Python 语言的示例实现。
import numpy as np
# 定义移动方向与对应编号的关系
directions = [(1, 0), (1, 1), (0, 1), (-1, 1),
(-1, 0), (-1, -1), (0, -1), (1, -1)]
dir2num = dict(((dx, dy), num) for num, (dx, dy) in enumerate(directions))
def get_chaincode(img, start):
""" 返回二维图片 img 中从 start 点开始的线条的链码 """
chaincode = []
cur = start # 当前点
prev = (0, 0) # 上一个点
pdir = 0 # 上一个点到当前点的移动方向
# 直到回到 start 点为止
while cur != start or not chaincode:
for i, d in enumerate(directions[pdir:] + directions[:pdir]):
# 沿着扫描方向顺序扫描周围的八个像素点
nextp = cur[0] + d[0], cur[1] + d[1]
if img[nextp] != 0:
# 找到下一个点
num = (pdir + i) % 8
chaincode.append(num)
prev, cur, pdir = cur, nextp, num
break
else:
# 无法顺时针找到下一个点
pdir = (pdir + 4) % 8 # 转180°,去找逆时针方向的点
return chaincode
def get_all_chaincodes(img):
""" 返回二维图片 img 中所有连通图的链码 """
chaincodes = []
painted = set()
h, w = img.shape[:2]
for y in range(h):
for x in range(w):
if img[y, x] != 0 and (y, x) not in painted:
# 找到起点,得到当前连通图的链码
chain = get_chaincode(img, (y, x))
chaincodes.append(chain)
# 标记该连通图中的所有像素点
for dy, dx in directions:
ny, nx = y + dy, x + dx
if ny >= 0 and ny < h and nx >= 0 and nx < w and img[ny, nx] != 0:
painted.add((ny, nx))
return chaincodes
def chaincode_to_string(chaincode):
""" 将一串链码转换为字符串 """
return "".join(str(c) for c in chaincode)
def string_to_chaincode(s):
""" 将字符串转换为一串链码 """
return [int(c) for c in s]
2D线的链码常被用于图像识别、模式匹配、手写数字识别等领域。它具有编码后数据量小、计算速度快、容易比较等优点。