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:

I need to convert this to an image matrix of variable dimensions with values 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. After this I would convert ImgMatrixDict to a list of lists.
Is this a viable idea?
PS: On performance, yes it would not be important as I won't be doing this in real time, but generally a code would be around 15-20 characters in length. I assumed a 50*50 by matrix would suffice for this purpose.
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()

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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With