2

Suppose I have a 8-direction freeman chain code as follows, in a python list:

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

Where directions would be defined as follows:

Freeman code directions

I need to convert this to an image matrix of variable dimensions with valules of 1s and 0s where 1s would depict the shape, as follows, for example:

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

Of course, the above is not an exact implementation of the above freeman code. Is there any implementation in python, or in any language that achieves this? My idea (in python): Use a defaultdict of defaultdicts with 0 as default:

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

and then start at a midpoint, say ImgMatrixDict[25][25], and then change values to 1 depending on the freeman code values as I traverse. Afte tis I would convert ImgMatrixDict to a list of lists.

Is this a viable idea or are there any existing libraries or suggestions to implement this? Any idea/pseudo-code would be appreciated.

PS: On performance, yes it would not be important as I won't be doing this in realtime, but generally a code would be around 15-20 charactors in length. I assumed a 50*50 by matrix would suffice for this purpose.

toing_toing
  • 2,334
  • 1
  • 37
  • 79
  • 2
    Can you define exactly the Freeman law you want to use ? Is it a 8 directions one ? An example that matches perfectly would be great, even a very short one. Are you concerned by performances ? – Vince Dec 17 '18 at 16:18
  • I added the information to the question, thanks :) – toing_toing Dec 17 '18 at 16:25

2 Answers2

3

If I am understanding your question correctly:

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

Kurtis Streutker
  • 1,157
  • 10
  • 13
1

Here is a solution in python. A dictionary is not adapted to this problem, you would better use a list of list to simulate the 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

Note that the image creation is a condensed expression of:

image = []
for y in range(D):
    line = []
    for x in range(D):
        line.append(0)
    image.append(line)

If one day, you need better performance for bigger images, there are solutions using numpy Library but requiring a good knowledge of basic python. Here is an example:

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)

Here, all loops built with 'for' on previous solution are fast-processed in C.

Vince
  • 336
  • 1
  • 11