Mathematical rectangle function Python - python

I want to make convolution of gaussian and rectangular functions like that:
from numpy import linspace, sqrt, sin, exp, convolve, abs
from matplotlib import pyplot as plt
def gauss(x, x0=0, sigma=1):
return exp(-1*(x-x0)**2/(2*sigma**2))
def rect(x):
return 1 if abs(x)<=0.5 else 0
x = linspace(-10, 10, 100)
f1 = gauss(x, sigma=1)
f2 = rect(x)
fsum = convolve(f1, f2)
y = linspace(-10, 10, 199)
plt.plot(x, f1)
plt.plot(x, f2)
plt.plot(y, fsum)
plt.show()
But I can't correctly describe rect function:
return 1 if abs(x)<=0.5 else 0
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Assuming you want an array of 0 and 1 values, the same shape as x, you can use numpy.where:
In [8]: x = np.linspace(-10, 10, 100)
In [9]: np.where(abs(x)<=0.5, 1, 0)
Out[9]:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0])
So your function could be:
from numpy import linspace, sqrt, sin, exp, convolve, abs, where
...
def rect(x):
return where(abs(x)<=0.5, 1, 0)

def rect(x):
y=x
for i in range(len(x)):
if abs(x[i]) <= 0.5:
y[i] = 1
else:
y[i] = 0
return y

Related

Different results for IRR from numpy.irr and the Excel IRR function

I have the following annual cash flows:
w=np.array([ -56501, -14918073, -1745198, -20887403, -9960686, -31076934,
0, 0, 11367846, 26736802, -2341940, 20853917,
22166416, 19214094, 23056582, -11227178, 18867100, 24947517,
28733869, 24707603, -17030396, 7753089, 27526723, 31534327,
26726270, -24607953, 11532035, 29444013, 24350595, 30140678,
-33262793, 5640172, 32846900, 38165710, 31655489, -74343373,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, -8727068])
I calculate IRR using np.irr
np.irr(w)
Out[141]: -0.05393588064654964
When I use IRR function in Excel for the same cash flows, I get 12%.
These two functions usually produce the same result. Does anyone know why in this case the results are so different? Thanks!
For the given cash flows, the IRR is not unique; see Multiple IRRs. Both the numpy and Excel values for r satisfy NPV(r) = 0, where NPV is the net present value.
Here's a plot of NPV(r) for the data in w. The red stars mark the IRR values (where NPV(r) is zero).
Here's the script that generates the plot:
import numpy as np
import matplotlib.pyplot as plt
w = np.array([ -56501, -14918073, -1745198, -20887403, -9960686, -31076934,
0, 0, 11367846, 26736802, -2341940, 20853917,
22166416, 19214094, 23056582, -11227178, 18867100, 24947517,
28733869, 24707603, -17030396, 7753089, 27526723, 31534327,
26726270, -24607953, 11532035, 29444013, 24350595, 30140678,
-33262793, 5640172, 32846900, 38165710, 31655489, -74343373,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, -8727068])
r_excel = 0.1200963665
r_numpy = np.irr(w)
rr = np.linspace(-0.055, 0.16, 500)
npvals = np.array([np.npv(r, w) for r in rr])
plt.plot(rr, npvals/1e6, alpha=0.8)
plt.plot(r_numpy, 0, 'r*')
plt.plot(r_excel, 0, 'r*')
plt.grid(True)
plt.xlabel('r')
plt.ylabel('NPV(r) [millions]')
plt.show()

matplotlib plot in a loop

How to connect every 10th point?
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
#points = np.fromfile('test_acc_history.txt')
points = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0])
plt.figure(100)
plt.plot(points)
plt.show()
The output results in:
BUT, I wanna have a result which should look like a curve:
In order to plot every nth point, you can slice the array, points[::n]. To then make sure to have them plotted at the correct position, you also need to supply a list of x values, which is every nth point from the integer number range.
import numpy as np
import matplotlib.pyplot as plt
points = np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0])
plt.plot(points)
plt.plot(range(len(points))[::10],points[::10] )
plt.show()

Avoid a deepcopy when doing a BFS

I'm currently solving the second exercise in this assignment (this is not homework, I'm actually trying to solve this other problem). My solution uses a BFS to search for the minimal solution to a variant of the "Lights Out" problem, in which pressing a light will flip the state of every light on the same row and the same column.
I think that my implementation is correct, but it's a bit too slow: it's currently taking 12+ seconds to run on my computer (which is unacceptable for my purposes).
from copy import deepcopy
from itertools import chain
from Queue import PriorityQueue
# See: http://www.seas.upenn.edu/~cis391/Homework/Homework2.pdf
class Puzzle(object):
def __init__(self, matrix):
self.matrix = matrix
self.dim = len(matrix)
def __repr__(self):
return str(self.matrix)
def solved(self):
return sum([sum(row) for row in self.matrix]) == 0
def move(self, i, j):
for k in range(self.dim):
self.matrix[i][k] = (self.matrix[i][k] + 1) % 2
self.matrix[k][j] = (self.matrix[k][j] + 1) % 2
self.matrix[i][j] = (self.matrix[i][j] + 1) % 2
return self
def copy(self):
return deepcopy(self)
def next(self):
result = []
for i in range(self.dim):
for j in range(self.dim):
result.append(self.copy().move(i, j))
return result
def solve(self):
q = PriorityQueue()
v = set()
q.put((0, self))
while True:
c = q.get()
if c[1].solved():
return c[0]
else:
for el in c[1].next():
t = el.tuple()
if t not in v:
v.add(t)
q.put((c[0] + 1, el))
def tuple(self):
return tuple(chain.from_iterable(self.matrix))
The culprit, according to cProfile, appears to be the deepcopy call. On the other hand, I see no alternatives: I need to add to the queue another Puzzle object containing a fresh copy of self.matrix.
How can I speed up my implementation?
Here's the test case that I'm using:
print Puzzle([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]).solve()
which should return 1 (we only need to press the light in the lower right corner).
EDIT: Here's another gnarly test case:
print Puzzle([
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
]).solve()
Its solution is at most 14: press all lights on the diagonal that were already on. Unfortunately, the impressive speedup by #zch isn't enough to solve this problem, leading me to believe that, due to the high branching factor, a BFS wasn't the right way to solve this problem.
There is a number of optimizations to be done.
First, avoid deepcopy, implement it your own copying (this by itself worked for me 5x faster):
class Puzzle(object):
def __init__(self, matrix):
self.matrix = [list(row) for row in matrix]
self.dim = len(matrix)
def copy(self):
return Puzzle(self.matrix)
Second, in BFS you don't need priority queue, use Queue or implement your own queuing. This gives some speedup. And third, check for being solved before putting it into the queue, not after taking things out. This should allow you to go one level deeper in comparable time:
def solve(self):
v = set()
q = [(0, self)]
i = 0
while True:
c = q[i]
i += 1
for el in c[1].next():
t = el.tuple()
if t not in v:
if el.solved():
return c[0] + 1
v.add(t)
q.append((c[0] + 1, el))
Further, using a list of list of bits is very memory-inefficient. You can pack all the bits into a single integer and get much faster solution. Additionally you can precompute masks for allowed moves:
def bits(iterable):
bit = 1
res = 0
for elem in iterable:
if elem:
res |= bit
bit <<= 1
return res
def mask(dim, i, j):
res = 0
for idx in range(dim * i, dim * (i + 1)):
res |= 1 << idx
for idx in range(j, dim * dim, dim):
res |= 1 << idx
return res
def masks(dim):
return [mask(dim, i, j) for i in range(dim) for j in range(dim)]
class Puzzle(object):
def __init__(self, matrix):
if isinstance(matrix, Puzzle):
self.matrix = matrix.matrix
self.dim = matrix.dim
self.masks = matrix.masks
else:
self.matrix = bits(sum(matrix, []))
self.dim = len(matrix)
self.masks = masks(len(matrix))
def __repr__(self):
return str(self.matrix)
def solved(self):
return self.matrix == 0
def next(self):
for mask in self.masks:
puzzle = Puzzle(self)
puzzle.matrix ^= mask
yield puzzle
def solve(self):
v = set()
q = [(0, self)]
i = 0
while True:
c = q[i]
i += 1
for el in c[1].next():
t = el.matrix
if t not in v:
if el.solved():
return c[0] + 1
v.add(t)
q.append((c[0] + 1, el))
And finally for another factor of 5 you can pass around just bit matrices, instead of whole Puzzle objects and additionally inline some most often used function.
def solve(self):
v = set()
q = [(0, self.matrix)]
i = 0
while True:
dist, matrix = q[i]
i += 1
for mask in self.masks:
t = matrix ^ mask
if t not in v:
if t == 0:
return dist + 1
v.add(t)
q.append((dist + 1, t))
For me these optimizations combined give speedup of about 250 times.
I changed solve to
def solve(self):
q = PriorityQueue()
v = set()
q.put((0, self))
while True:
c = q.get()
if c[1].solved():
return c[0]
else:
for i in range(self.dim):
for j in range(self.dim):
el = c[1].move(i, j) # do the move
t = el.tuple()
if t not in v:
v.add(t)
q.put((c[0] + 1, el.copy())) # copy only as needed
c[1].move(i, j) # undo the move
As .move(i, j) is its own inverse. Copies are made but only when the state has not been visited. This reduces the time from 7.405s to 5.671s. But this is not as big an improvement as expected.
Then replacing def tuple(self): with:
def tuple(self):
return tuple(tuple(r) for r in self.matrix)
reduces the time from 5.671s to 0.531s. That should do it.
Full listing:
from copy import deepcopy
from Queue import PriorityQueue
# See: http://www.seas.upenn.edu/~cis391/Homework/Homework2.pdf
class Puzzle(object):
def __init__(self, matrix):
self.matrix = matrix
self.dim = len(matrix)
def __repr__(self):
return str(self.matrix)
def solved(self):
return sum([sum(row) for row in self.matrix]) == 0
def move(self, i, j):
for k in range(self.dim):
self.matrix[i][k] = (self.matrix[i][k] + 1) % 2
self.matrix[k][j] = (self.matrix[k][j] + 1) % 2
self.matrix[i][j] = (self.matrix[i][j] + 1) % 2
return self
def copy(self):
return deepcopy(self)
def solve(self):
q = PriorityQueue()
v = set()
q.put((0, self))
while True:
c = q.get()
if c[1].solved():
return c[0]
else:
for i in range(self.dim):
for j in range(self.dim):
el = c[1].move(i, j) # do the move
t = el.tuple()
if t not in v:
v.add(t)
q.put((c[0] + 1, el.copy())) # copy only as needed
c[1].move(i, j) # undo the move
def tuple(self):
return tuple(tuple(r) for r in self.matrix)
print Puzzle([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]).solve()

Python Equivalent for bwmorph

I am still coding a fingerprint image preprocessor on Python. I see in MATLAB there is a special function to remove H breaks and spurs:
bwmorph(a , 'hbreak')
bwmorph(a , 'spur')
I have searched scikit, OpenCV and others but couldn't find an equivalent for these two use of bwmorph. Can anybody point me to right direction or do i have to implement my own?
Edit October 2017
the skimage module now has at least 2 options:
skeletonize and thin
Example with comparison
from skimage.morphology import thin, skeletonize
import numpy as np
import matplotlib.pyplot as plt
square = np.zeros((7, 7), dtype=np.uint8)
square[1:-1, 2:-2] = 1
square[0, 1] = 1
thinned = thin(square)
skel = skeletonize(square)
f, ax = plt.subplots(2, 2)
ax[0,0].imshow(square)
ax[0,0].set_title('original')
ax[0,0].get_xaxis().set_visible(False)
ax[0,1].axis('off')
ax[1,0].imshow(thinned)
ax[1,0].set_title('morphology.thin')
ax[1,1].imshow(skel)
ax[1,1].set_title('morphology.skeletonize')
plt.show()
Original post
I have found this solution by joefutrelle on github.
It seems (visually) to give similar results as the Matlab version.
Hope that helps!
Edit:
As it was pointed out in the comments, I'll extend my initial post as the mentioned link might change:
Looking for a substitute in Python for bwmorph from Matlab I stumbled upon the following code from joefutrelle on Github (at the end of this post as it's very long).
I have figured out two ways to implement this into my script (I'm a beginner and I'm sure there are better ways!):
1) copy the whole code into your script and then call the function (but this makes the script harder to read)
2) copy the code it in a new python file 'foo' and save it. Now copy it in the Python\Lib (eg. C:\Program Files\Python35\Lib) folder. In your original script you can call the function by writing:
from foo import bwmorph_thin
Then you'll feed the function with your binary image:
skeleton = bwmorph_thin(foo_image, n_iter = math.inf)
import numpy as np
from scipy import ndimage as ndi
# lookup tables for bwmorph_thin
G123_LUT = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0,
1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1,
0, 0, 0], dtype=np.bool)
G123P_LUT = np.array([0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0,
0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0], dtype=np.bool)
def bwmorph_thin(image, n_iter=None):
"""
Perform morphological thinning of a binary image
Parameters
----------
image : binary (M, N) ndarray
The image to be thinned.
n_iter : int, number of iterations, optional
Regardless of the value of this parameter, the thinned image
is returned immediately if an iteration produces no change.
If this parameter is specified it thus sets an upper bound on
the number of iterations performed.
Returns
-------
out : ndarray of bools
Thinned image.
See also
--------
skeletonize
Notes
-----
This algorithm [1]_ works by making multiple passes over the image,
removing pixels matching a set of criteria designed to thin
connected regions while preserving eight-connected components and
2 x 2 squares [2]_. In each of the two sub-iterations the algorithm
correlates the intermediate skeleton image with a neighborhood mask,
then looks up each neighborhood in a lookup table indicating whether
the central pixel should be deleted in that sub-iteration.
References
----------
.. [1] Z. Guo and R. W. Hall, "Parallel thinning with
two-subiteration algorithms," Comm. ACM, vol. 32, no. 3,
pp. 359-373, 1989.
.. [2] Lam, L., Seong-Whan Lee, and Ching Y. Suen, "Thinning
Methodologies-A Comprehensive Survey," IEEE Transactions on
Pattern Analysis and Machine Intelligence, Vol 14, No. 9,
September 1992, p. 879
Examples
--------
>>> square = np.zeros((7, 7), dtype=np.uint8)
>>> square[1:-1, 2:-2] = 1
>>> square[0,1] = 1
>>> square
array([[0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
>>> skel = bwmorph_thin(square)
>>> skel.astype(np.uint8)
array([[0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
"""
# check parameters
if n_iter is None:
n = -1
elif n_iter <= 0:
raise ValueError('n_iter must be > 0')
else:
n = n_iter
# check that we have a 2d binary image, and convert it
# to uint8
skel = np.array(image).astype(np.uint8)
if skel.ndim != 2:
raise ValueError('2D array required')
if not np.all(np.in1d(image.flat,(0,1))):
raise ValueError('Image contains values other than 0 and 1')
# neighborhood mask
mask = np.array([[ 8, 4, 2],
[16, 0, 1],
[32, 64,128]],dtype=np.uint8)
# iterate either 1) indefinitely or 2) up to iteration limit
while n != 0:
before = np.sum(skel) # count points before thinning
# for each subiteration
for lut in [G123_LUT, G123P_LUT]:
# correlate image with neighborhood mask
N = ndi.correlate(skel, mask, mode='constant')
# take deletion decision from this subiteration's LUT
D = np.take(lut, N)
# perform deletion
skel[D] = 0
after = np.sum(skel) # coint points after thinning
if before == after:
# iteration had no effect: finish
break
# count down to iteration limit (or endlessly negative)
n -= 1
return skel.astype(np.bool)
"""
# here's how to make the LUTs
def nabe(n):
return np.array([n>>i&1 for i in range(0,9)]).astype(np.bool)
def hood(n):
return np.take(nabe(n), np.array([[3, 2, 1],
[4, 8, 0],
[5, 6, 7]]))
def G1(n):
s = 0
bits = nabe(n)
for i in (0,2,4,6):
if not(bits[i]) and (bits[i+1] or bits[(i+2) % 8]):
s += 1
return s==1
g1_lut = np.array([G1(n) for n in range(256)])
def G2(n):
n1, n2 = 0, 0
bits = nabe(n)
for k in (1,3,5,7):
if bits[k] or bits[k-1]:
n1 += 1
if bits[k] or bits[(k+1) % 8]:
n2 += 1
return min(n1,n2) in [2,3]
g2_lut = np.array([G2(n) for n in range(256)])
g12_lut = g1_lut & g2_lut
def G3(n):
bits = nabe(n)
return not((bits[1] or bits[2] or not(bits[7])) and bits[0])
def G3p(n):
bits = nabe(n)
return not((bits[5] or bits[6] or not(bits[3])) and bits[4])
g3_lut = np.array([G3(n) for n in range(256)])
g3p_lut = np.array([G3p(n) for n in range(256)])
g123_lut = g12_lut & g3_lut
g123p_lut = g12_lut & g3p_lut
"""`
You will have to implement those on your own since they aren't present in OpenCV or skimage as far as I know.
However, it should be straightforward to check MATLAB's code on how it works and write your own version in Python/NumPy.
Here is a guide describing in detail NumPy functions exclusively for MATLAB users, with hints on equivalent functions in MATLAB and NumPy:
Link

Why does pyplot.quiver plots vectors with infinite length?

I am plotting a 5X10 matrix of vectors using pyplot.quiver :
from pylab import *
COLUMN_RESOLUTION = 10
ROW_RESOLUTION = 5
plotBorders = 2
X,Y = meshgrid(arange(COLUMN_RESOLUTION),arange(ROW_RESOLUTION)) # X,Y positions of vectors
U = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1.0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1.0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
V = [0, 0, 0, 0, -1.0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1.0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
lim = 10
xlim(-1*lim,lim)
ylim(-1*lim,lim)
quiver(X,Y, U, V)
show()
The resulting figure has vectors with infinite length - no matter how much I extend the axes (the parameter lim) The arrows' head is not seen :
lim = 10
lim = 100
What am I doing wrong?
Thanks!
Use the "scale" parameter in the quiver command:
quiver(X,Y, U, V, scale=20.0)

Categories