Table of contents
array representation of the image
Analysis of "Hand-drawn Effects of Images"
array representation of the image
-
RGB color mode of the image
The image generally uses the RGB color mode, that is, the color of each pixel is composed of red (R), green (G), and blue (B).
The change and superposition of the three color channels of RGB get various colors, among which
- R red, value range, 0‐255
- G green, value range, 0‐255
- B blue, value range, 0‐255
The colors formed by RGB include all colors that can be perceived by human vision.
-
PIL library
PIL——Python Image Library
The PIL library is a third-party library with powerful image processing capabilities. The installation method under the command line:
#安装
pip install pillow
#引入包
from PIL import Image
Image is a class (object) in the PIL library that represents an image.
-
image composition
An image is a two-dimensional matrix of pixels, each element is an RGB value, which is (R, G, B). The image is a three-dimensional array with dimensions of height, width, and pixel RGB values.
from PIL import Image
import numpy as np
im=np.array(Image.open("beijing.jpg"))
print(im.shape,im.dtype)
its output is
(669, 1012, 3) uint8
image transformation
We will finish reading the image, get the pixel RGB value, modify it and save it as a new file.
Let's first take a look at the image that complements each pixel:
from PIL import Image
import numpy as np
a=np.array(Image.open("beijing.jpg"))
b=[255,255,255]-a
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')
Let's take a look at the image after grayscale processing, leaving two channels.
from PIL import Image
import numpy as np
a=np.array(Image.open("beijing.jpg").convert("L"))
b=255-a
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')
Interval transform after grayscale image
from PIL import Image
import numpy as np
a=np.array(Image.open("beijing.jpg").convert("L"))
b=(100/255)*a+150
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')
Pixel square after grayscale image
from PIL import Image
import numpy as np
a=np.array(Image.open("beijing.jpg").convert("L"))
b=255*(a/255)**2
im=Image.fromarray(b.astype("uint8"))
im.save('./new.jpg')
Then everyone has seen it, we only need to modify its b.
hand-drawn effect of the image
-
Hand-painted effect display
Several characteristics of the hand-painted effect:
- black and white gray
- The border lines are heavier
- The same or similar colors tend to be white
- Slight light effect
-
Code display and explanation
from PIL import Image
import numpy as np
a = np.asarray(Image.open('./beijing.jpg').convert('L')).astype('float')
depth = 10. # (0-100)
grad = np.gradient(a) #取图像灰度的梯度值
grad_x, grad_y = grad #分别取横纵图像梯度值
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.
A = np.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1./A
vec_el = np.pi/2.2 # 光源的俯视角度,弧度值
vec_az = np.pi/4. # 光源的方位角度,弧度值
dx = np.cos(vec_el)*np.cos(vec_az) #光源对x 轴的影响
dy = np.cos(vec_el)*np.sin(vec_az) #光源对y 轴的影响
dz = np.sin(vec_el) #光源对z 轴的影响
b = 255*(dx*uni_x + dy*uni_y + dz*uni_z) #光源归一化
b = b.clip(0,255)
im = Image.fromarray(b.astype('uint8')) #重构图像
im.save('./beijingHD.jpg')
Gradient reconstruction
The image is reconstructed using the gradient value between pixels and the virtual depth value, and the distance of human vision is simulated according to the grayscale change.
depth = 10.
grad = np.gradient(a)
grad_x, grad_y = grad
grad_x = grad_x*depth/100.
grad_y = grad_y*depth/100.
The preset depth value of depth is 10, and its value range is 0-100, and then the gradient values in the x and y directions are extracted, and the gradient values in the x and y directions are adjusted according to the depth.
light effect
According to the change of gray scale, it simulates the distance of human vision.
- Design a virtual light source that sits diagonally above the image
- The top-down angle of the light source relative to the image is Elevation, and the azimuth is Azimuth
- Establish the influence function of the light source on the gradient value of each point
- Calculate the new pixel value of each point
vec_el = np.pi/2.2
vec_az = np.pi/4.
dx = np.cos(vec_el)*np.cos(vec_az)
dy = np.cos(vec_el)*np.sin(vec_az)
dz = np.sin(vec_el)
np.cos(vec_el) is the projection length of the unit light on the ground plane, dx, dy, dz are the degree of influence of the light source on the three directions of x/y/z.
Gradient normalization
A = np.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/A
uni_y = grad_y/A
uni_z = 1./A
b = 255*(dx*uni_x + dy*uni_y + dz*uni_z)
A is a three-dimensional normalized unit coordinate system that constructs the x and y axis gradients, and then the gradient interacts with the light source to convert the gradient to grayscale
image generation
b = b.clip(0,255)
im = Image.fromarray(b.astype('uint8')) #重构图像
im.save('./beijingHD.jpg')
Here, in order to avoid data out of bounds, the generated gray value is clipped to the 0-255 interval