Hello everyone, I’m Xiao Zhang, long time no see
This tweet is about computer vision. It takes less than 20 lines of Python code to transform an image from a natural wind to a hand-drawn wind without any pre-processing or post-processing. Only two common libraries are used in the code, with Numpy taking care of the core calculations and Pillow taking care of image reading and writing
Before we get started, take a look at the initial results. Here’s a before and after comparison of individual images
FIG. 1
Figure 2
FIG. 3
In order to increase the interest, this code is later applied to a video, plus a background music, fresh “hand-painted wind video” out
Python hand-painted wind video production!
“Hand-painted wind” implementation steps
Before explaining this, there are three main features of hand-drawn graphics that need to be understood:
- The picture should be grayscale and single channel.
- The edges of the lines are heavily painted black, and the same or similar pixel values tend to white;
- With the help of light source, the change of gray level can simulate the effect of human vision
Read the image and convert it to an array
Because the pixel calculation is needed later, the read image is converted into an array for convenience
a = np.asarray(Image.open("Annie1.jpg").convert('L')).astype('float')
Copy the code
Calculate and normalize the gradient values of x,y and Z axes
The most effective way to locate the edge part of the image is to calculate the gradient. The grayscale change is used to simulate the effect of the image near and far. Depth indicates the preset depth, and the default gradient of z axis is 1
Depth = 10. # (0-100) grad = np.gradient(a) # Grad_x = grad_x * depth / 100. Grad_y = grad_y * depth / 100Copy the code
The gradient value is normalized
A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1. / A
Copy the code
Add light effect
In addition to calculating the gradient value of hand-painted wind images, the influence of light source should also be considered. According to the incident Angle of light source, the gradient values on x, Y and Z axes are most affected to different degrees. A simulated light source is added and placed above the inclined Angle to form two included angles with X and Y respectively
And the two included angles are known through experiments, and then the final new pixel value is calculated according to the sine and cosine function
Vec_el = Np.pi / 2.2 # Overlooking Angle of the light source, radian value VEC_az = Np.pi / 4. # Azimuth Angle of the light source, radian value dx = NP.cos (VEC_EL) * Np.cos (VEC_az) # Influence of the light source on the X-axis dy Dz = Np.sin (vec_EL) # Influence of light source on the z-axis b = 255 * (dx * uni_x + dy * uni_y + dz * Uni_z)# light source normalization,8 255 b = B.lip (0, 255)# Truncate the part of pixel value lower than 0 and higher than 255Copy the code
Export the image and save it
im.save("Annie_shouhui.jpg")
Copy the code
Here is all the code involved in this step
from PIL import Image import numpy as np a = np.asarray(Image.open("Annie1.jpg").convert('L')).astype('float') depth = 10. # (0-100) grad = np.gradient(a) # take the image grayscale gradient grad_x, Grad_y = grad_y * depth / 100. A = np. SQRT (grad_x ** 2 + 1.) uni_x = grad_x/A uni_y = grad_y/A uni_z = 1. / A VEC_el = Np.pi / 2.2 # Light source overlooking Angle, radian value vec_az = Np.pi 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 B = 255 * (dx * uni_x + dy * uni_y + dz * uni_z) # Light source normalization b = b.lip (0, 255) im = image.fromarray (B.uint8 ('uint8')) # Save (" annie_shouhui.jpg ")Copy the code
Make hand-drawn wind videos
Although the effect of picture transformation is good, but the picture is static, after all, as a visual animal, if it can be made dynamic that is the best, know the above method, just on the video plus a frame merging operation, you can make a hand-painted wind video effect
You-get Download the video
So here I use the you-get command to find a video on B, download it,
you-get --format=dash-flv -o ./ https://www.bilibili.com/video/BV1tT4y1j7a9?from=search&8014393453748720686
Copy the code
After downloading, use OpenCV2 to cut the frame of the video, and transform the picture into a local video file at the same time
vc = cv2.VideoCapture(video_path) c = 0 if vc.isOpened(): rval,frame = vc.read() height,width = frame.shape[0],frame.shape[1] print(height, width) else: # jpg_list = [os.path.join('Pic_Directory/', I) for I in os.listdir('Pic_Directory') If I.E NDSwith ('.jpg')] FPS = 24 # Video_path1 = './text.mp4' video_writer = cv2.VideoWriter(video_path1,cv2.VideoWriter_fourcc(*'mp4v'),fps,(width,height)) while rval: Img = coonvert_jpg(image.fromarray (frame)) frame_converted = np.array(img) # convert to a 3-way Image = np.expand_dims(frame_converted,axis = 2) result_arr = np.concatenate((image,image,image),axis = -1) video_writer.write(result_arr) print('Sucessfully Conveted---------{}'.format(c)) c = c + 1 if c >= 3000: break video_writer.release()Copy the code
In the image sequence extraction, we need to pay attention to one point, because the transformed image is a single channel, directly with the help of OpenCV generated video sequence is unable to play, need to add a step to convert a single channel into three channels!
Image = np.expand_dims(frame_converted,axis = 2) result_arr = np.concatenate((image,image,image),axis = -1)Copy the code
If you want to make the generated video feel better, you can add a background music by using editing software or Python. It is recommended to use editing software, because the customized audio effect of Python is not ideal, and real-time feedback is required when adding music, but Python cannot meet this requirement for the time being
Data source code acquisition
The source code involved in the article will get the data, pay attention to wechat public number: Xiao Zhang Python, background reply keyword: 210322 can!
summary
This article mainly introduces how to convert an image into hand-painted style, in Python code quantity but rarely involves the knowledge related to mathematics, physics, so it is not easy to understand, this article is designed to introduce image hand-painted wind conversion have so a kind of method, of course, if an interested friend can study
That’s all for this article, thanks for reading, and we’ll see you next time