The tortuosity can be defined as "It has irregular bends, curves and undulations and in different ways." So the calculation of a descriptor (and a index) may represent the capacity of that sample (person) of produce tortuosity (in general one calculate a mean and a std, I will not delve into those calculations). Another (personal) definition that i like is "if i take this point, how far can move without changing his direction" (and perhaps, this definition was implemented).
In general this solution requiere a binary image (handwritting). the procedure is create a copy layer (that I call draft) and then, depending on the conectivity, send to compute that binary matrix in a recursive way.
This code considers the connectivity by 4, and by 8, and I think that could be improvement by connectivity by 16.
- By 4: horizontal and vertical.
- By 8: 4 plus their diagonals ( in 45°).
- (by 16, every 22°)
But for the problem that this code was created, the results in the test sets did not indicate the need for the extension of connectivity
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import math
import numpy as np
def __conect(image, pos, vect):
limits = np.shape(image)
if pos[0] < 0 or pos[0] == limits[0] or pos[1]< 0 or pos[1] == limits[1]:
return 0
elif image[pos]:
return 1+__conect(image,(pos[0]+vect[0],pos[1]+vect[1]),vect)
return 0
def conect(image, label=4):
draft = np.zeros(np.shape(image)).astype(int)
image = image.astype(bool)
pos=np.where(image==True)
for i in range(len(pos[0])):
weights = []
if label in [4, 8]:
weights.append(__conect(image,(pos[0][i],pos[1][i]+1),(0,1))+__conect(image,(pos[0][i],pos[1][i]-1),(0,-1))) #vertical
weights.append(__conect(image,(pos[0][i]+1,pos[1][i]),(1,0))+__conect(image,(pos[0][i]-1,pos[1][i]),(-1,0))) #horizontal
if label in [8]:
weights.append(__conect(image,(pos[0][i]+1,pos[1][i]+1),(1,1))+__conect(image,(pos[0][i]-1,pos[1][i]-1),(-1,-1))) #slash
weights.append(__conect(image,(pos[0][i]-1,pos[1][i]+1),(-1,1))+__conect(image,(pos[0][i]+1,pos[1][i]-1),(+1,-1))) #backsalsh
draft[pos[0][i],pos[1][i]]= 1+max(weights)
return draft
I like to consider this an example of named (optional) arguments, recursion, and move through a binary matrix without the double **for**.
Input
image = np.array([[0,0,0,0,0,0,0],
[0,1,0,0,0,0,0],
[0,1,1,1,1,1,0],
[0,1,1,1,1,1,0],
[0,1,1,1,1,1,0],
[0,1,1,1,1,1,0],
[0,0,0,0,0,1,1]])
print("Original: \n", image)
print("Connect 4 (by default):\n", conect(image))
print("Connect set in 8:\n", conect(image, label=8))
Output
Original:
[[0 0 0 0 0 0 0]
[0 1 0 0 0 0 0]
[0 1 1 1 1 1 0]
[0 1 1 1 1 1 0]
[0 1 1 1 1 1 0]
[0 1 1 1 1 1 0]
[0 0 0 0 0 1 1]]
Connect 4 (by default):
[[0 0 0 0 0 0 0]
[0 5 0 0 0 0 0]
[0 5 5 5 5 5 0]
[0 5 5 5 5 5 0]
[0 5 5 5 5 5 0]
[0 5 5 5 5 5 0]
[0 0 0 0 0 5 2]]
Connect set in 8:
[[0 0 0 0 0 0 0]
[0 6 0 0 0 0 0]
[0 5 6 5 5 5 0]
[0 5 5 6 5 5 0]
[0 5 5 5 6 5 0]
[0 5 5 5 5 6 0]
[0 0 0 0 0 5 6]]
My 'test codes'
They are small sections of code for try something that maybe i don't know, or I don't want to test in the main project because of the iterance necesaries to work well. Usually are related with some current project (work), sometimes are to improve something else (debug, printing, algorithms, efficiency, etc...).
I have many of those files (called test#.py or delete#.py), so, I will try to explain why I think they are interesting, and I hope that for you too.
If you consider that I had bad English, I apologize, it is not my native language.
Top comments (0)