📜  2D线的链码(1)

📅  最后修改于: 2023-12-03 15:13:07.885000             🧑  作者: Mango

2D线的链码

简介

2D线的链码是一种用来表示二维空间内连续的线条的编码方式。它将每个像素点与它相邻的像素点连接起来,形成连续的线条,然后通过数字编码对这些连续线条进行描述。

算法流程

算法的输入是一个二维的图片数组,输出为一串数字,表示该图片的线条。

  1. 从图片中任选一点作为起点,顺时针扫描周围的8个像素点,找到第一个非白色像素点并记录下该点的坐标和编号。

  2. 用该点坐标替换当前点坐标,并将该点的编号存储,重复步骤1,直到回到起点点。

  3. 对每个连通图(由多条连续线条组成)进行同样的编码。

  4. 对于多个连通图,将它们的编码按顺序连接起来,作为最终的编码结果。

代码实现

代码实现的具体细节会因不同的编程语言而有所不同,下面给出一个 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线的链码常被用于图像识别、模式匹配、手写数字识别等领域。它具有编码后数据量小、计算速度快、容易比较等优点。