### preface

The goddess who has been in love for many years suddenly came to me today. Is she

Here's the thing:

Goddess: can you turn a portrait into a hand-painted picture

Own: Yes, no problem!

Does she finally know what I mean and want to send me her private photo alone!

No way, the goddess's wish must be met. start!

Main technical points adopted:

**Python + Numpy + PIL**

Before starting the text code, let's take a look at the comparison between the original picture and the converted hand-painted wind picture.

Of course, I first checked the three basic features of hand painting:

- Single channel grayscale image
- Heavy edge lines can be regarded as black, and the same or similar pixel values tend to white
- Under the effect of light source, the gray change is similar to the distance of human vision

Let's start with the implementation steps of hand drawn photos:

**Read the picture and convert it into an array**

Because to calculate the pixels of the image, you can first convert the image into an array. The code is as follows:

```
a =np.asarray(Image.open("man.jpg").convert('L')).astype('float')
```

**Calculate the gradient values of X, y and Z axes and normalize them**

The photo focuses more on the edge area. Calculating the gradient is the most effective way to locate the edge part of the picture. The gray change is used to simulate the far and near effect of the picture. Depth represents the preset depth, and the default gradient of z-axis is 1.

```
depth = ten. # (0-100)
grad =np.gradient(a) #Take the gradient value of image gray level
grad_ x,grad_ y =grad #Take the gradient values of horizontal and vertical images respectively
grad_ x =grad_ x *depth / one hundred.
grad_ y =grad_ y *depth / one hundred.
```

Normalize the gradient value

```
A =np.sqrt(grad_x ** two +grad_y ** two + one.)
uni_ x =grad_ x /A
uni_ y =grad_ y /A
uni_ z = one. /A
```

**Add lighting effect**

According to the different incident angles of the light source, it has different degrees of influence on the gradient values on the X, y and Z axes. Add a simulated light source, place it above the slope, form two included angles with X and Y respectively, and finally calculate the new pixel value with sine cosine function.

```
vec_ el =np.pi / two point two #Top view angle of light source, radian value
vec_ az =np.pi / four. #Azimuth angle of light source, radian value
dx =np.cos(vec_el) *np.cos(vec_az) #Influence of light source on X-axis
dy =np.cos(vec_el) *np.sin(vec_az) #Influence of light source on y-axis
dz =np.sin(vec_el) #Influence of light source on z-axis
b = two hundred and fifty-five * (dx *uni_x +dy *uni_y +dz *uni_z) #Light source normalization, 8 255
b =b.clip(0, two hundred and fifty-five)#Truncate the part whose pixel value is lower than 0 and higher than 255
```

- Export the picture and save it

```
im.save("man_shouhui.jpg")
```

All right~

It's so easy to convert a picture into hand-painted style in Python!

Don't say it. Hurry to tell the goddess that the task she assigned has been completed!

Creation is not easy, white whoring is not good. Your support and recognition is the biggest driving force for my creation. See you in the next article!

Dragon youth

If there are any mistakes in this blog, please comment and advice. Thank you very much!