从弗里曼链码生成图像矩阵
Generate image matrix from Freeman chain code
假设我有一个 8 向自由人链码如下,在 python 列表中:
freeman_code = [3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5]
方向定义如下:
我需要将其转换为具有 1s 和 0s 值的可变维度图像矩阵,其中 1s 表示形状,如下所示,例如:
image_matrix = [
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 1, 1]
]
当然,以上并不是上面freeman代码的精确实现。 python 或 any 语言中是否有实现此目的的实现?
我的想法(python):
使用默认为 0 的 defaultdicts 的 defaultdict:
ImgMatrixDict = defaultdict(lambda: defaultdict(lambda:0))
然后从中点开始,比如 ImgMatrixDict[25][25]
,然后根据我遍历的自由人代码值将值更改为 1。之后我会将 ImgMatrixDict
转换为列表列表。
这是一个可行的想法,还是有任何现有的库或建议来实现它?任何 idea/pseudo-code 将不胜感激。
PS:在性能方面,是的,这并不重要,因为我不会实时执行此操作,但通常代码的长度约为 15-20 个字符。我假设 50*50 的矩阵就足够了。
如果我没有正确理解你的问题:
import numpy as np
import matplotlib.pyplot as plt
freeman_code = [3, 3, 3, 6, 6, 4, 6, 7, 7, 0, 0, 6]
img = np.zeros((10,10))
x, y = 4, 4
img[y][x] = 1
for direction in freeman_code:
if direction in [1,2,3]:
y -= 1
if direction in [5,6,7]:
y += 1
if direction in [3,4,5]:
x -= 1
if direction in [0,1,7]:
x += 1
img[y][x] = 1
plt.imshow(img, cmap='binary', vmin=0, vmax=1)
plt.show()
这是 python 中的解决方案。字典不适应这个问题,你最好用一个list of list来模拟table.
D = 10
# DY, DX
FREEMAN = [(0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1), (1, 0), (1, 1)]
freeman_code = [3, 3, 3, 3, 6, 6, 6, 6, 0, 0, 0, 0]
image = [[0]*D for x in range(D)]
y = D/2
x = D/2
image[y][x] = 1
for i in freeman_code:
dy, dx = FREEMAN[i]
y += dy
x += dx
image[y][x] = 1
print("freeman_code")
print(freeman_code)
print("image")
for line in image:
strline = "".join([str(x) for x in line])
print(strline)
>0000000000
>0100000000
>0110000000
>0101000000
>0100100000
>0111110000
>0000000000
>0000000000
>0000000000
>0000000000
请注意,图像创建是以下内容的浓缩表达式:
image = []
for y in range(D):
line = []
for x in range(D):
line.append(0)
image.append(line)
如果有一天,您需要更好的性能来处理更大的图像,可以使用 numpy 库找到解决方案,但需要很好的基础知识 python。这是一个例子:
import numpy as np
D = 10
# DY, DX
FREEMAN = [(0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1), (1, 0), (1, 1)]
DX = np.array([1, 1, 0, -1, -1, -1, 0, 1])
DY = np.array([0, -1, -1, -1, 0, 1, 1, 1])
freeman_code = np.array([3, 3, 3, 3, 6, 6, 6, 6, 0, 0, 0, 0])
image = np.zeros((D, D), int)
y0 = D/2
x0 = D/2
image[y0, x0] = 1
dx = DX[freeman_code]
dy = DY[freeman_code]
xs = np.cumsum(dx)+x0
ys = np.cumsum(dy)+y0
print(xs)
print(ys)
image[ys, xs] = 1
print("freeman_code")
print(freeman_code)
print("image")
print(image)
在这里,所有在以前的解决方案中使用 'for' 构建的循环都在 C 中快速处理。
假设我有一个 8 向自由人链码如下,在 python 列表中:
freeman_code = [3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5]
方向定义如下:
我需要将其转换为具有 1s 和 0s 值的可变维度图像矩阵,其中 1s 表示形状,如下所示,例如:
image_matrix = [
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 1, 1]
]
当然,以上并不是上面freeman代码的精确实现。 python 或 any 语言中是否有实现此目的的实现? 我的想法(python): 使用默认为 0 的 defaultdicts 的 defaultdict:
ImgMatrixDict = defaultdict(lambda: defaultdict(lambda:0))
然后从中点开始,比如 ImgMatrixDict[25][25]
,然后根据我遍历的自由人代码值将值更改为 1。之后我会将 ImgMatrixDict
转换为列表列表。
这是一个可行的想法,还是有任何现有的库或建议来实现它?任何 idea/pseudo-code 将不胜感激。
PS:在性能方面,是的,这并不重要,因为我不会实时执行此操作,但通常代码的长度约为 15-20 个字符。我假设 50*50 的矩阵就足够了。
如果我没有正确理解你的问题:
import numpy as np
import matplotlib.pyplot as plt
freeman_code = [3, 3, 3, 6, 6, 4, 6, 7, 7, 0, 0, 6]
img = np.zeros((10,10))
x, y = 4, 4
img[y][x] = 1
for direction in freeman_code:
if direction in [1,2,3]:
y -= 1
if direction in [5,6,7]:
y += 1
if direction in [3,4,5]:
x -= 1
if direction in [0,1,7]:
x += 1
img[y][x] = 1
plt.imshow(img, cmap='binary', vmin=0, vmax=1)
plt.show()
这是 python 中的解决方案。字典不适应这个问题,你最好用一个list of list来模拟table.
D = 10
# DY, DX
FREEMAN = [(0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1), (1, 0), (1, 1)]
freeman_code = [3, 3, 3, 3, 6, 6, 6, 6, 0, 0, 0, 0]
image = [[0]*D for x in range(D)]
y = D/2
x = D/2
image[y][x] = 1
for i in freeman_code:
dy, dx = FREEMAN[i]
y += dy
x += dx
image[y][x] = 1
print("freeman_code")
print(freeman_code)
print("image")
for line in image:
strline = "".join([str(x) for x in line])
print(strline)
>0000000000
>0100000000
>0110000000
>0101000000
>0100100000
>0111110000
>0000000000
>0000000000
>0000000000
>0000000000
请注意,图像创建是以下内容的浓缩表达式:
image = []
for y in range(D):
line = []
for x in range(D):
line.append(0)
image.append(line)
如果有一天,您需要更好的性能来处理更大的图像,可以使用 numpy 库找到解决方案,但需要很好的基础知识 python。这是一个例子:
import numpy as np
D = 10
# DY, DX
FREEMAN = [(0, 1), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1), (1, 0), (1, 1)]
DX = np.array([1, 1, 0, -1, -1, -1, 0, 1])
DY = np.array([0, -1, -1, -1, 0, 1, 1, 1])
freeman_code = np.array([3, 3, 3, 3, 6, 6, 6, 6, 0, 0, 0, 0])
image = np.zeros((D, D), int)
y0 = D/2
x0 = D/2
image[y0, x0] = 1
dx = DX[freeman_code]
dy = DY[freeman_code]
xs = np.cumsum(dx)+x0
ys = np.cumsum(dy)+y0
print(xs)
print(ys)
image[ys, xs] = 1
print("freeman_code")
print(freeman_code)
print("image")
print(image)
在这里,所有在以前的解决方案中使用 'for' 构建的循环都在 C 中快速处理。