Create a structuringselement in the form of a line with a certain degree and length
Type hints

def bresenham(x0, y0, x1, y1):


should be, at a guess,

def bresenham(x0: float, y0: float, x1: float, y1: float) -&gt; List[float]:


or maybe int, but you get the idea.

Type promotion

You don't need decimals here:

err = dx / 2.0


/2 will accomplish the same thing.

Termination

What happens if you call bresenham(0, 0, 9.5, 9.5)? I suspect that it will iterate infinitely and hang, due to

  while x != x1:


One way to fix this, if your algorithm permits, is - rather than making an sx dependent on the comparison of x0 and x1, simply swap x0 and x1 if they're in the wrong order. Then, rather than !=, use &lt;, and you don't have to calculate sx.

Use a generator

For some use cases this will dramatically decrease memory consumption. Instead of building up points in memory, just yield whenever you have a point. Allow the caller to decide whether they want to cast to a list, a tuple, or just iterate over the points.

Int casting

  n_rows = int(2 * max([abs(point_y) for point_y in points_y]) + 1)


is overambitious in application of the int cast. The multiplication and addition don't need to be done in floating-point math, so you can instead do

  n_rows = 2 * int(max(abs(point_y) for point_y in points_y)) + 1


Also note that you shouldn't pass a list to max - just pass the generator directly.