Appending a list to a list in a loop (Python) - python

I have a Python list with values, say:
a = [[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]]
I want to append in a loop a new list 'b' to the list 'a'.
b = [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]]
The result should look like (when adding 'b' once to 'a'):
[[[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]], [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]]]
Now, I want to append the list b N times to the list a.
Both a and b have shape (4,3)
The result should then have shape: (N+1,4,3)
How do I do this?

Native Python Lists will not behave the way you expect here as described in a few comments, so if you can use a 3rd party library, consider NumPy, which will behave more like a matrix of values as you expect and can then be converted back into a Python List
Setup
>>> a = [[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]]
>>> b = [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]]
Replicate b vertically
the second argument to np.tile() describes the replications in each dimension
.reshape() to prepare it as a 3-dimensional array
>>> import numpy as np
>>> b_tiled = np.tile(np.array(b), (4,1)).reshape(4,4,3)
>>> b_tiled
array([[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]]])
Collect a and b_tiled into the same array
NOTE a should be reshaped or [a] to match the shape of b_tiled
>>> np.vstack((np.array([a]), b_tiled))
array([[[0, 0, 0],
[1, 0, 1],
[1, 1, 0],
[0, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]],
[[2, 1, 0],
[3, 0, 1],
[4, 1, 0],
[2, 1, 1]]])
.tolist()
You can use .tolist() to make a native Python list again, though it may be more convenient to you as a numpy array
>>> np.vstack((np.array([a]), b_tiled)).tolist()
[[[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]], [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]], [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]], [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]], [[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]]]

Wrapping up my contributions to this discussion into an actual answer, summarizing what I think are the two best solutions:
1 Using NumPy arrays
Start from #Andreas' solution, but follow #ti7's lead and wrap the results into a numpy array, which manages the memory correctly:
result = np.array([a] + [b] * 5)
This solution brings the results into much more usable and versatile NumPy arrays.
2 Using deepcopy
Start from #Andreas' solution, and add a deep copy so the result does not alias parts of the array together:
import copy
result = [a] + [copy.deepcopy(b) for _ in range(5)]
This solution keeps the results as standard Python lists of lists.
Kuddos to #ti7 for noticing that the deep copy had to be done by instance of b rather than over the results, since deepcopy does not break aliasing that is internal to its input; and to #Andreas for assembling this line of code from the comments.
Caveat: since a is not deep copied here, result[0] is an alias for a, and changes to either will change both. Deep copy a too to avoid this.

add the lists and multiply the second list:
l = [a] + [b]*5
[[[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]],
[[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]],
[[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]],
[[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]],
[[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]],
[[2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]]]
In case you want to modify the list values later on, be aware that you actually have 5x the SAME list referenced (as mentioned by #ti7), this means if you change one value in list b you change all, like this:
l[1][1][1] = "foo"
[[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1]]
[[2, 1, 0], [3, 'foo', 1], [4, 1, 0], [2, 1, 1]]
[[2, 1, 0], [3, 'foo', 1], [4, 1, 0], [2, 1, 1]]
[[2, 1, 0], [3, 'foo', 1], [4, 1, 0], [2, 1, 1]]
[[2, 1, 0], [3, 'foo', 1], [4, 1, 0], [2, 1, 1]]
[[2, 1, 0], [3, 'foo', 1], [4, 1, 0], [2, 1, 1]]
to avoid that use (as mentioned by #joanis):
l = [a] + [copy.deepcopy(b) for _ in range(5)]

[a+b*5] this will create
[[[0, 0, 0], [1, 0, 1], [1, 1, 0], [0, 1, 1], [2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1], [2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1], [2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1], [2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1], [2, 1, 0], [3, 0, 1], [4, 1, 0], [2, 1, 1]]]

Related

How do I accept "divide by zero" as zero? (Python)

So I have the following code:
import numpy as np
array1 = np.array([[[[2, 2, 3], [0, 2, 0], [2, 0, 0]],
[[1, 2, 2], [2, 2, 0], [0, 2, 3]],
[[0, 4, 2], [2, 2, 2], [2, 2, 3]]],
[[[2, 3, 0], [3, 2, 0], [2, 0, 3]],
[[0, 2, 2], [2, 2, 0], [2, 2, 3]],
[[1, 0, 2], [2, 2, 2], [2, 2, 0]]],
[[[2, 0, 0], [0, 2, 0], [2, 0, 0]],
[[2, 2, 2], [0, 2, 0], [2, 2, 0]],
[[0, 2, 2], [2, 2, 2], [2, 2, 0]]]])
array2 = np.array([[[[2, 2, 3], [0, 2, 0], [2, 0, 0]],
[[1, 2, 2], [2, 2, 0], [0, 2, 3]],
[[0, 4, 2], [2, 2, 2], [2, 2, 3]]],
[[[2, 3, 0], [3, 2, 0], [2, 0, 3]],
[[0, 2, 2], [2, 10, 0], [2, 2, 3]],
[[1, 0, 2], [2, 2, 2], [2, 2, 0]]],
[[[2, 0, 0], [0, 2, 0], [2, 0, 0]],
[[2, 2, 2], [0, 2, 0], [2, 2, 0]],
[[0, 2, 2], [2, 2, 2], [2, 2, 0]]]])
def calc(x, y):
result = y/x
return result
final_result = []
for x, y in zip(array1, array2):
final_result.append(calc(np.array(x), np.array(y)))
So all in all I have two lists that include some 3D arrays, and then I have defined a function. The last part is where I use each 3D array in the function, and I ultimately end up with a list (final_result) of some other 3D arrays where the function has been used on each entry from array1 and array2.
However, as you can see, array1 which ultimately gives the x values in the function does have 0 values in some of the entries. And yes, mathematically, this is no good. But in this case, I really just need the entries that does have a zero x-entry to be zero. So it doesn't need to run the function whenever that happens, but just skip it, and leave that entry as zero.
Can this be done?
This question has been answered here. Numpy has a specific way to catch such errors:
def calc( a, b ):
""" ignore / 0, div0( [-1, 0, 1], 0 ) -> [0, 0, 0] """
with np.errstate(divide='ignore', invalid='ignore'):
c = np.true_divide( a, b )
c[ ~ np.isfinite( c )] = 0 # -inf inf NaN
return c

Using function with entries from two 3D arrays (Python)

So let's say I have two arrays (numpy arrays that is):
array1 =
[[[1, 0, 0], [0, 6, 0], [3, 0, 0]],
[[0, 2, 4], [0, 4, 0], [0, 4, 0]],
[[0, 0, 2], [1, 3, 2], [3, 4, 0]]]
and
array2 =
[[[2, 4, 0], [0, 4, 0], [3, 0, 0]],
[[0, 0, 3], [1, 4, 3], [2, 4, 3]],
[[0, 0, 1], [0, 2, 1], [1, 0, 2]]]
I then make a function like:
def array_calc(x,y,z):
x*y+z
What I would like to do now is have the x-values come from array1 and y-values from array2, and z-values just a constant I choose (let's say z = 0), and then do the calculation on each entry of the arrays, and ultimately end up with a new array, where the calculation has been done, and I get something like:
array_result =
[[[2, 0, 0], [0, 24, 0], [9, 0, 0]],
[[0, 0, 12], [0, 16, 0], [0, 16, 0]],
[[0, 0, 2], [0, 6, 2], [3, 0, 0]]]
But, I'm not quite sure how that is done.
If your arrays are numpy arrays, it is as simple as:
import numpy as np
x = np.array([[1,0],[0,1]])
y = np.array([[4,1],[0,2]])
z = 1
result = x*y + z
# result = array([[5, 1], [1, 3]])
Using simple for loops:
import numpy as np
def array_calc(x, y, z):
"""Returns x * y + z with x and y 3D Numpy arrays and z a number"""
new_arr = x.copy()
for i in np.arange(x.shape[0]):
for k in np.arange(x.shape[1]):
for j in np.arange(x.shape[2]):
new_arr[i, k, j] = x[i, k, j] * y[i, k, j] + z
return new_arr
With:
array1 = np.array([[[1, 0, 0], [0, 6, 0], [3, 0, 0]],
[[0, 2, 4], [0, 4, 0], [0, 4, 0]],
[[0, 0, 2], [1, 3, 2], [3, 4, 0]]])
array2 = np.array([[[2, 4, 0], [0, 4, 0], [3, 0, 0]],
[[0, 0, 3], [1, 4, 3], [2, 4, 3]],
[[0, 0, 1], [0, 2, 1], [1, 0, 2]]])
Returns:
array([[[ 3, 1, 1],
[ 1, 25, 1],
[10, 1, 1]],
[[ 1, 1, 13],
[ 1, 17, 1],
[ 1, 17, 1]],
[[ 1, 1, 3],
[ 1, 7, 3],
[ 4, 1, 1]]])
A way I can think of is to iterate through them and perform your calculations.
This can be done with 3 dimensional arrays too but I just found it easier to do it with 2 dimensional arrays. I am sure there are other ways to reduce the complexity further down because 3 for loops is not the best solution but it gets the work done.
The code is here:
array1 = [[[1, 0, 0], [0, 6, 0], [3, 0, 0]],[[0, 2, 4], [0, 4, 0], [0, 4, 0]],[[0, 0, 2], [1, 3, 2], [3, 4, 0]]]
array2 = [[[2, 4, 0], [0, 4, 0], [3, 0, 0]], [[0, 0, 3], [1, 4, 3], [2, 4, 3]], [[0, 0, 1], [0, 2, 1], [1, 0, 2]]]
z=0
array_1 = reduce(list.__add__, array1)
array_2 = reduce(list.__add__, array2)
array_3 = [[0,0,0] for _ in xrange(9)]
len_array=9
for i in range(len_array):
for l in range(3):
array_3[i][l] = array_1[i][l]*array_2[i][l]+z
print array_3

Python class variable referenced from within list

As an attempt to further my knowledge in python, I have started to create a very simple tic tac toe AI.
Currently, I am stumped at some behavior I have not expected from python where when I append a class instance variable to a local list and change the item in the local list, the instance variable will have changed too.
How can I change only the local list element without affecting the class instance variable?
This is the extract of the program which is affected:
class ticAI:
def __init__(self, board):
self.board = board
self.tic = tictactoe(board)
def calc(self):
possibilities = []
ycord = 0
for y in self.board:
xcord = 0
for x in y:
if x == 0:
possibilities.append(self.board)
possibilities[len(possibilities)-1][ycord][xcord] = 2
print(self.board)
xcord += 1
ycord += 1
self.board looks like this:
[
[0, 0, 0],
[0, 1, 0],
[0, 0, 0]
]
and outputs this:
[[2, 0, 0], [0, 1, 0], [0, 0, 0]]
[[2, 2, 0], [0, 1, 0], [0, 0, 0]]
[[2, 2, 2], [0, 1, 0], [0, 0, 0]]
[[2, 2, 2], [2, 1, 0], [0, 0, 0]]
[[2, 2, 2], [2, 1, 2], [0, 0, 0]]
[[2, 2, 2], [2, 1, 2], [2, 0, 0]]
[[2, 2, 2], [2, 1, 2], [2, 2, 0]]
[[2, 2, 2], [2, 1, 2], [2, 2, 2]]
it should however, output this:
[[2, 0, 0], [0, 1, 0], [0, 0, 0]]
[[0, 2, 0], [0, 1, 0], [0, 0, 0]]
[[0, 0, 2], [0, 1, 0], [0, 0, 0]]
[[0, 0, 0], [2, 1, 0], [0, 0, 0]]
[[0, 0, 0], [0, 1, 2], [0, 0, 0]]
[[0, 0, 0], [0, 1, 0], [2, 0, 0]]
[[0, 0, 0], [0, 1, 0], [0, 2, 0]]
[[0, 0, 0], [0, 1, 0], [0, 0, 2]]
As made aware by #jonrsharpe, you can use deepcopy to create a copy of a variable.
Original code:
possibilities.append(self.board)
possibilities[len(possibilities)-1][ycord][xcord] = 2
print(self.board)
New code:
b = copy.deepcopy(self.board)
possibilities.append(b)
possibilities[len(possibilities)-1][ycord][xcord] = 2
print(self.board)

Sort a list of lists containing integers

I've got a list of lists containing integers sorted at the moment by the sum of the contents:
[[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 2], [0, 1, 1], [0, 2, 0], [1, 0, 1], [1, 1, 0], [2, 0, 0], [0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0], [1, 0, 2], [1, 1, 1], [1, 2, 0], [2, 0, 1], [2, 1, 0], [3, 0, 0], [0, 0, 4], [0, 1, 3], [0, 2, 2], [0, 3, 1], [0, 4, 0], [1, 0, 3], [1, 1, 2], [1, 2, 1], [1, 3, 0], [2, 0, 2], [2, 1, 1], [2, 2, 0], [3, 0, 1], [3, 1, 0], [4, 0, 0]]
I would like to sort them in ascending order by the common structure of its contents i.e like
[[1, 0, 0], [2, 0, 0], [3, 0, 0], [4, 0, 0], [0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 4, 0], [0, 0, 1], [0, 0, 2], [0,0,3], [0,0,4]... ]
I have seen the docs but I can't figure out how I can do this.
Is this what you're after...
>>> l = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 2], [0, 1, 1], [0, 2, 0], [1, 0, 1], [1, 1, 0], [2, 0, 0], [0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0], [1, 0, 2], [1, 1, 1], [1, 2, 0], [2, 0, 1], [2, 1, 0], [3, 0, 0], [0, 0, 4], [0, 1, 3], [0, 2, 2], [0, 3, 1], [0, 4, 0], [1, 0, 3], [1, 1, 2], [1, 2, 1], [1, 3, 0], [2, 0, 2], [2, 1, 1], [2, 2, 0], [3, 0, 1], [3, 1, 0], [4, 0, 0]]
>>> l.sort(key=lambda x: (-x.count(0), x[::-1]))
>>> l
[[1, 0, 0], [2, 0, 0], [3, 0, 0], [4, 0, 0], [0, 1, 0], [0, 2, 0], [0, 3, 0], [0, 4, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 0, 4], [1, 1, 0], [2, 1, 0], [3, 1, 0], [1, 2, 0], [2, 2, 0], [1, 3, 0], [1, 0, 1], [2, 0, 1], [3, 0, 1], [0, 1, 1], [0, 2, 1], [0, 3, 1], [1, 0, 2], [2, 0, 2], [0, 1, 2], [0, 2, 2], [1, 0, 3], [0, 1, 3], [1, 1, 1], [2, 1, 1], [1, 2, 1], [1, 1, 2]]
See http://docs.python.org/2/howto/sorting.html for an explanation of the Python sort capability, including a discussion of "Key Functions" which gives you whatever additional flexibility you need beyond the basic sort.
Use your sorting criteria function as key in the sorting.
input_list = [[1, 0, 0], [0, 1, 0], [0, 0, 1], [0, 0, 2], [0, 1, 1], [0, 2, 0], [1, 0, 1], [1, 1, 0], [2, 0, 0], [0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0], [1, 0, 2], [1, 1, 1], [1, 2, 0], [2, 0, 1], [2, 1, 0], [3, 0, 0], [0, 0, 4], [0, 1, 3], [0, 2, 2], [0, 3, 1], [0, 4, 0], [1, 0, 3], [1, 1, 2], [1, 2, 1], [1, 3, 0], [2, 0, 2], [2, 1, 1], [2, 2, 0], [3, 0, 1], [3, 1, 0], [4, 0, 0]]
sorted_list = sorted(input_list,key=my_sorting_func)

hit and miss transform for detecting branched point and endpoint in scikit-image

I have 2 functions that use mahotas python library for detecting branched point and end point in an image.
The 2 functions:
def branchedPoints(skel):
branch1=np.array([[2, 1, 2], [1, 1, 1], [2, 2, 2]])
branch2=np.array([[1, 2, 1], [2, 1, 2], [1, 2, 1]])
branch3=np.array([[1, 2, 1], [2, 1, 2], [1, 2, 2]])
branch4=np.array([[2, 1, 2], [1, 1, 2], [2, 1, 2]])
branch5=np.array([[1, 2, 2], [2, 1, 2], [1, 2, 1]])
branch6=np.array([[2, 2, 2], [1, 1, 1], [2, 1, 2]])
branch7=np.array([[2, 2, 1], [2, 1, 2], [1, 2, 1]])
branch8=np.array([[2, 1, 2], [2, 1, 1], [2, 1, 2]])
branch9=np.array([[1, 2, 1], [2, 1, 2], [2, 2, 1]])
br1=mh.morph.hitmiss(skel,branch1)
br2=mh.morph.hitmiss(skel,branch2)
br3=mh.morph.hitmiss(skel,branch3)
br4=mh.morph.hitmiss(skel,branch4)
br5=mh.morph.hitmiss(skel,branch5)
br6=mh.morph.hitmiss(skel,branch6)
br7=mh.morph.hitmiss(skel,branch7)
br8=mh.morph.hitmiss(skel,branch8)
br9=mh.morph.hitmiss(skel,branch9)
return br1+br2+br3+br4+br5+br6+br7+br8+br9
def endPoints(skel):
endpoint1=np.array([[0, 0, 0],[0, 1, 0],[2, 1, 2]])
endpoint2=np.array([[0, 0, 0],[0, 1, 2],[0, 2, 1]])
endpoint3=np.array([[0, 0, 2],[0, 1, 1],[0, 0, 2]])
endpoint4=np.array([[0, 2, 1],[0, 1, 2],[0, 0, 0]])
endpoint5=np.array([[2, 1, 2],[0, 1, 0],[0, 0, 0]])
endpoint6=np.array([[1, 2, 0],[2, 1, 0],[0, 0, 0]])
endpoint7=np.array([[2, 0, 0],[1, 1, 0],[2, 0, 0]])
endpoint8=np.array([[0, 0, 0],[2, 1, 0],[1, 2, 0]])
ep1=mh.morph.hitmiss(skel,endpoint1)
ep2=mh.morph.hitmiss(skel,endpoint2)
ep3=mh.morph.hitmiss(skel,endpoint3)
ep4=mh.morph.hitmiss(skel,endpoint4)
ep5=mh.morph.hitmiss(skel,endpoint5)
ep6=mh.morph.hitmiss(skel,endpoint6)
ep7=mh.morph.hitmiss(skel,endpoint7)
ep8=mh.morph.hitmiss(skel,endpoint8)
ep = ep1+ep2+ep3+ep4+ep5+ep6+ep7+ep8
return ep
There is a way to obtain these functions with Scikit-image library?
Morphology section of scikit image hasn't got hit and miss transform.
from scipy import ndimage
ndimage.binary_hit_or_miss(...)
import mahotas as mh
def branchedPoints(skel, showSE=True):
X=[]
#cross X
X0 = np.array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]])
X1 = np.array([[1, 0, 1],
[0, 1, 0],
[1, 0, 1]])
X.append(X0)
X.append(X1)
#T like
T=[]
#T0 contains X0
T0=np.array([[2, 1, 2],
[1, 1, 1],
[2, 2, 2]])
T1=np.array([[1, 2, 1],
[2, 1, 2],
[1, 2, 2]]) # contains X1
T2=np.array([[2, 1, 2],
[1, 1, 2],
[2, 1, 2]])
T3=np.array([[1, 2, 2],
[2, 1, 2],
[1, 2, 1]])
T4=np.array([[2, 2, 2],
[1, 1, 1],
[2, 1, 2]])
T5=np.array([[2, 2, 1],
[2, 1, 2],
[1, 2, 1]])
T6=np.array([[2, 1, 2],
[2, 1, 1],
[2, 1, 2]])
T7=np.array([[1, 2, 1],
[2, 1, 2],
[2, 2, 1]])
T.append(T0)
T.append(T1)
T.append(T2)
T.append(T3)
T.append(T4)
T.append(T5)
T.append(T6)
T.append(T7)
#Y like
Y=[]
Y0=np.array([[1, 0, 1],
[0, 1, 0],
[2, 1, 2]])
Y1=np.array([[0, 1, 0],
[1, 1, 2],
[0, 2, 1]])
Y2=np.array([[1, 0, 2],
[0, 1, 1],
[1, 0, 2]])
Y2=np.array([[1, 0, 2],
[0, 1, 1],
[1, 0, 2]])
Y3=np.array([[0, 2, 1],
[1, 1, 2],
[0, 1, 0]])
Y4=np.array([[2, 1, 2],
[0, 1, 0],
[1, 0, 1]])
Y5=np.rot90(Y3)
Y6 = np.rot90(Y4)
Y7 = np.rot90(Y5)
Y.append(Y0)
Y.append(Y1)
Y.append(Y2)
Y.append(Y3)
Y.append(Y4)
Y.append(Y5)
Y.append(Y6)
Y.append(Y7)
bp = np.zeros(skel.shape, dtype=int)
for x in X:
bp = bp + mh.morph.hitmiss(skel,x)
for y in Y:
bp = bp + mh.morph.hitmiss(skel,y)
for t in T:
bp = bp + mh.morph.hitmiss(skel,t)
if showSE==True:
fig = plt.figure(figsize=(4,5))
tX =['X0','X1']
tY =['Y'+str(i) for i in range(0,8)]
tT =['T'+str(i) for i in range(0,8)]
ti= tX+tY+tT
SE=X+Y+T
print len(SE), len(ti)
n = 1
ti = iter(ti)
for se in SE:
#print next(ti)
#print se
mycmap = mpl.colors.ListedColormap(['black','blue','red'])
ax = fig.add_subplot(4,5,n,frameon=False, xticks=[], yticks=[])
title(str(next(ti)))
imshow(se, interpolation='nearest',vmin=0,vmax=2,cmap=mycmap)
n = n+1
fig.subplots_adjust(hspace=0.1,wspace=0.08)
#ax_cb = fig.add_axes([.9,.25,.1,.3])#
color_vals=[0,1,2]
#cb = mpl.colorbar.ColorbarBase(ax_cb,cmap=mycmap, ticks=color_vals)
#cb.set_ticklabels(['back', 'hit', 'don\'t care'])
plt.show()
return bp
def endPoints(skel):
endpoint1=np.array([[0, 0, 0],
[0, 1, 0],
[2, 1, 2]])
endpoint2=np.array([[0, 0, 0],
[0, 1, 2],
[0, 2, 1]])
endpoint3=np.array([[0, 0, 2],
[0, 1, 1],
[0, 0, 2]])
endpoint4=np.array([[0, 2, 1],
[0, 1, 2],
[0, 0, 0]])
endpoint5=np.array([[2, 1, 2],
[0, 1, 0],
[0, 0, 0]])
endpoint6=np.array([[1, 2, 0],
[2, 1, 0],
[0, 0, 0]])
endpoint7=np.array([[2, 0, 0],
[1, 1, 0],
[2, 0, 0]])
endpoint8=np.array([[0, 0, 0],
[2, 1, 0],
[1, 2, 0]])
ep1=mh.morph.hitmiss(skel,endpoint1)
ep2=mh.morph.hitmiss(skel,endpoint2)
ep3=mh.morph.hitmiss(skel,endpoint3)
ep4=mh.morph.hitmiss(skel,endpoint4)
ep5=mh.morph.hitmiss(skel,endpoint5)
ep6=mh.morph.hitmiss(skel,endpoint6)
ep7=mh.morph.hitmiss(skel,endpoint7)
ep8=mh.morph.hitmiss(skel,endpoint8)
ep = ep1+ep2+ep3+ep4+ep5+ep6+ep7+ep8
return ep
a = np.array([[0,0,0,0,0,0],
[0,0,1,0,1,0],
[0,1,1,0,1,0],
[0,0,0,1,0,0],
[0,0,1,0,1,0],
[0,1,0,0,0,0]])
lab,_ = mh.label(a>0)
sk =mh.thin(a)
print a.dtype, sk.dtype
bp = branchedPoints(a>0)
h = mh.labeled.labeled_size(bp)
ep = endPoints(a)
subplot(141)
title('skeleton')
imshow(a,interpolation='nearest')
subplot(142)
title('label')
imshow(lab,interpolation='nearest')
subplot(143)
title('junction')
imshow(bp,interpolation='nearest')
subplot(144)
title('end-points')
imshow(ep,interpolation='nearest')
The structuring elements can be plotted:
Branched points and end-points can be detected from a skeleton-like shape:
from a bigger image:

Categories

Resources