Генерация матрицы изображений из кода цепочки Freeman - PullRequest
0 голосов
/ 17 декабря 2018

Предположим, у меня есть код цепи Freeman с 8 направлениями, как показано ниже, в списке Python:

freeman_code = [3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5]

Где направления будут определены следующим образом:

Freeman code directions

Мне нужно преобразовать это в матрицу изображения переменных размеров со значениями 1 и 0, где 1 будет отображать форму, например, следующим образом:

image_matrix = [
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 1, 1]
]

ИзКонечно, вышеупомянутое не является точной реализацией вышеуказанного кода Freeman.Есть ли какая-либо реализация в python или в любом языке, который достигает этого?Моя идея (в Python): использовать defaultdict defaultdicts с 0 по умолчанию:

ImgMatrixDict = defaultdict(lambda: defaultdict(lambda:0))

, а затем начать с средней точки, скажем ImgMatrixDict[25][25], а затем изменить значения на 1 в зависимости от значений кода Freemanкогда я пересекаюПосле этого я бы преобразовал ImgMatrixDict в список списков.

Это жизнеспособная идея или есть какие-либо библиотеки или предложения для реализации этого?Любая идея / псевдокод будет принята с благодарностью.

PS: С точки зрения производительности, это не важно, поскольку я не буду заниматься этим в режиме реального времени, но обычно код будет состоять из 15-20 символов вдлина.Я предположил, что для этой цели будет достаточно матрицы 50 * 50.

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

Вот решение в Python.Словарь не адаптирован к этой проблеме, вам лучше использовать список списка для имитации таблицы.

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.

0 голосов
/ 17 декабря 2018

Если я правильно понимаю ваш вопрос:

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()

enter image description here

...