DEV Community

loading...

Tortuosity in Python, test_code_#001

elem3ntal profile image Elem3ntal Development ・3 min read

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


Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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]]


Enter fullscreen mode Exit fullscreen mode

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.

Discussion (0)

pic
Editor guide