Stroke Algorithm in python Here is my next Numpy practice, I am not sure is it more accurate to call it "Stroke Algorithm" or "Draw edge stuff", xD. 

Anyway I did in steps:


calculate each pixel's RGB absolute distance to pixels on its right and down side, the distance is simple measured by absolute different in each color value and sum them up.
if the absolute distance on both directions all larger than some particular value, then it is an edge pixel, and color it black, else white




Suggestions I am looking for


Any suggestions in Numpy, I have some duplicate code this time, and didn't find good way to remove them.


Full code:

# -*- coding: utf-8 -*-
import numpy as np
from PIL import Image

def stroke(image_path, output, level=80, edge_color=[255,255,255], blackground_color=[0,0,0]):
    img = Image.open(image_path)
    data = np.asarray(img, dtype="int32")

    w, h, k = data.shape
    dirright_data = np.concatenate((data[:, 1:], data[:,-1:]), axis=1)
    dirdown_data = np.concatenate((data[1:,:], data[-1:,:]), axis=0)

    disRight = np.absolute(np.sum(data - dirright_data, axis=2))
    disDown = np.absolute(np.sum(data - dirdown_data, axis=2))

    level = min(max(1,level), 255)
    D_right = np.asarray(disRight&lt;=level, dtype="int32")
    D_down = np.asarray(disDown&lt;=level, dtype="int32")

    D = (D_right+D_down) &gt; 1
    neg_D = (D_right+D_down) &lt;= 1
    data[D] = edge_color
    data[neg_D] = blackground_color

    img = Image.fromarray(np.asarray(np.clip(data, 0, 255), dtype="uint8"), "RGB")
    img.save(output)

if __name__ == "__main__":
    stroke("images/bob.png", "new_test.jpg")
I find your numpy code to be quite rational as far as my skills go, but your script have several things to improve on besides that.

Improvable in current scope :


Removing duplicate code thanks to a helper function
Painting the whole background to simplify
Removing (yet) unecessary line w, h, k = data.shape
Naming error, or logic error ? Background and edge color seem swapped. Changing &lt;= level to &gt; level
Some non-compliant and unexplicit variable names




Code showing this

# -*- coding: utf-8 -*-
import numpy as np
from PIL import Image

def get_dist_array(data, shifted_data, level):
    distance_map = np.absolute(np.sum(data - shifted_data, axis=2))
    return np.asarray(distance_map &gt; level, dtype="int32")

def stroke(image_path, output, level=80, edge_color=[255,255,255], blackground_color=[0,0,0]):
    img = Image.open(image_path)
    data = np.asarray(img, dtype="int32")
    level = min(max(1,level), 255)
    edges_right = get_dist_array(data, np.concatenate((data[:, 1:], data[:,-1:]), axis=1), level)
    edges_down = get_dist_array(data, np.concatenate((data[1:,:], data[-1:,:]), axis=0), level)
    data[:] = blackground_color
    edges = (edges_right+edges_down) &gt; 1
    data[edges] = edge_color
    img = Image.fromarray(np.asarray(np.clip(data, 0, 255), dtype="uint8"), "RGB")
    img.save(output)

if __name__ == "__main__":
    stroke("images/bob.png", "new_test.jpg")




Other things to consider worth improving :


Get rid of hardcoded file names. You could use argparse here
RGBA support ?