程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

New year new weather, 100 lines of Python code to make dynamic firecrackers

編輯:Python

「 This is my participation 2022 For the first time, the third challenge is 2 God , Check out the activity details :2022 For the first time, it's a challenge 」


0 Write it at the front

Set off firecrackers to celebrate the Spring Festival , It has a history of more than 2000 years in China . About the origin of firecrackers , There is an interesting legend .

There is something in the mountains of the West , Long Chi Yu , One foot , Sex is not afraid of people . It's cold and hot , It's called Nian Jingwei , Later generations looked like it , With gunpowder .——《 Miraculous Scripture 》

At the beginning, people burned bamboo and exploded , To scare away mandrills that harm people . It is said that mandrills are most afraid of fire and noise , So every new year's Eve , People will “ Burn bamboo ”, Scare away mandrills . Year after year , It's like setting off firecrackers in the new year 、 Light the candle 、 Beating gongs and drums to celebrate the new year .

New Year , Let's make one with code today Dynamic firecrackers , The effect is as follows .

The basic principle of dynamic firecrackers is : Reproduce a recorded firecracker video in the form of character painting , The basic steps are Frame sampling Frame by frame conversion to character painting Character painting synthesis video . Let's start !

1 Video frame sampling

The function is shown below , The main function is to save the video image stream frame by frame to a specific cache folder ( If the folder does not exist, it will be created automatically ). Function input vp yes openCV Video handle , Output number Is the number of pictures converted .

def video2Pic(vp):
number = 0
if vp.isOpened():
r,frame = vp.read()
if not os.path.exists('cachePic'):
os.mkdir('cachePic')
os.chdir('cachePic')
else:
r = False
while r:
number += 1
cv2.imwrite(str(number)+'.jpg',frame)
r,frame = vp.read()
os.chdir("..")
return number
 Copy code 

2 Turn picture into character picture

2.1 Create pixels - Character index

Function input pixel RGBA value , Output the corresponding character code . Its principle is to evenly distribute the characters in the whole gray range , The character code corresponds to the range in which the pixel gray value falls . Character codes can be referenced ASCII code

ASCII Code use specified 7 Bit or 8 Bit binary arrays are used to represent 128 or 256 Possible characters . standard ASCII Code is also called basis ASCII code , Use 7 Bit binary number ( The rest 1 Bit binary is 0) To represent all uppercase and lowercase letters , Numbers 0 To 9、 Punctuation , And special control characters used in American English . among :0~31 And 127( common 33 individual ) Is a control character or a communication-specific character ( The rest are displayable characters ), Such as the controller :LF( Line break )、CR( enter )、FF( Change the page )、DEL( Delete )、BS( Backspace )、BEL( Ring the bell ) etc. ; Communication specific characters :SOH( Title )、EOT( Epilogue )、ACK( confirm ) etc. ;ASCII The value is 8、9、10 and 13 Convert to backspace 、 Tabulation 、 Line feed and carriage return characters . They don't have a specific graphic display , But depending on the application , It has different effects on text display .

RGBA Represent Red( Red )、Green( green )、Blue( Blue ) and Alpha Color space ,Alpha Channels are generally used as opacity parameters . If a pixel's alpha The channel value is 0%, Then it is completely transparent , And the value is 100% It means a completely opaque pixel ( Traditional digital image ).gray=0.2126 * r + 0.7152 * g + 0.0722 * b yes RGB Empirical formula for converting to gray value , Human eyes are more sensitive to green .

def color2Char(r,g,b,alpha = 256):
imgChar= list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ")
if alpha:
gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
unit = 256 / len(imgChar)
return imgChar[int(gray / unit)]
else:
return ''
 Copy code 

2.2 Convert pictures to characters pixel by pixel

The core code is as follows , Traverse each pixel of the picture

 img = Image.open(imagePath).convert('RGB').resize((imgWidth, imgHeight),Image.NEAREST)
for i in range(imgHeight):
for j in range(imgWidth):
pixel = img.getpixel((j, i))
color.append((pixel[0],pixel[1],pixel[2]))
txt = txt + color2Char(pixel[0], pixel[1], pixel[2], pixel[3]) if len(pixel) == 4 else \
txt + color2Char(pixel[0], pixel[1], pixel[2])
txt += '\n'
color.append((255,255,255))
 Copy code 

3 Synthesize character images into video

Input parameters vp yes openCV Video handle ,number It's the number of frames ,savePath Is the video save path , Function MP42 It is an encoding method that can generate smaller and smaller video files , Other things like that are isom、mp41、avc1、qt etc. , Express “ best ” Based on which format to parse the current file .

def img2Video(vp, number, savePath):
videoFourcc = VideoWriter_fourcc(*"MP42") # Set up video encoder 
asciiImgPathList = ['cacheChar' + r'/{}.jpg'.format(i) for i in range(1, number + 1)]
asciiImgTemp = Image.open(asciiImgPathList[1]).size
videoWritter= VideoWriter(savePath, videoFourcc, vp.get(cv2.CAP_PROP_FPS), asciiImgTemp)
for imagePath in asciiImgPathList:
videoWritter.write(cv2.imread(imagePath))
videoWritter.release()
 Copy code 

4 Complete code

import cv2
from PIL import Image,ImageFont,ImageDraw
import os
from cv2 import VideoWriter, VideoWriter_fourcc
''' * @breif: Convert pixel colors to ASCII character * @param[in]: Pixels RGBA value * @retval: character '''
def color2Char(r,g,b,alpha = 256):
imgChar = list("#RMNHQODBWGPZ*@$C&98?32I1>!:-;. ")
if alpha:
gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
unit = 256 / len(imgChar)
return imgChar[int(gray / unit)]
else:
return ''
''' * @breif: Convert video frame by frame to picture * @param[in]: vp -> openCV Video handle * @retval: number -> Number of pictures converted '''
def video2Pic(vp):
number = 0
if vp.isOpened():
r,frame = vp.read()
if not os.path.exists('cachePic'):
os.mkdir('cachePic')
os.chdir('cachePic')
else:
r = False
while r:
number += 1
cv2.imwrite(str(number)+'.jpg',frame)
r,frame = vp.read()
os.chdir("..")
return number
''' * @breif: Convert pictures pixel by pixel to ASCII character * @param[in]: imagePath -> Picture path * @param[in]: index -> Picture index * @retval: None '''
def img2Char(imagePath, index):
# initialization 
txt, color, font = '', [], ImageFont.load_default().font
imgWidth, imgHeight = Image.open(imagePath).size
asciiImg = Image.new("RGB",(imgWidth, imgHeight), (255,255,255))
drawPtr = ImageDraw.Draw(asciiImg)
imgWidth, imgHeight = int(imgWidth / 6), int(imgHeight / 15)
# Convert image frames pixel by pixel to ASCII Character and record RGB value 
img = Image.open(imagePath).convert('RGB').resize((imgWidth, imgHeight),Image.NEAREST)
for i in range(imgHeight):
for j in range(imgWidth):
pixel = img.getpixel((j, i))
color.append((pixel[0],pixel[1],pixel[2]))
txt = txt + color2Char(pixel[0], pixel[1], pixel[2], pixel[3]) if len(pixel) == 4 else \
txt + color2Char(pixel[0], pixel[1], pixel[2])
txt += '\n'
color.append((255,255,255))
# draw ASCII Draw and save characters 
x, y = 0,0
fontW, fontH = font.getsize(txt[1])
fontH *= 1.37
for i in range(len(txt)):
if(txt[i]=='\n'):
x += fontH
y = -fontW
drawPtr.text((y,x), txt[i], fill=color[i])
y += fontW
os.chdir('cacheChar')
asciiImg.save(str(index)+'.jpg')
os.chdir("..")
''' * @breif: Convert the video to ASCII Image set * @param[in]: number -> frames * @retval: None '''
def video2Char(number):
if not os.path.exists('cacheChar'):
os.mkdir('cacheChar')
img_path_list = ['cachePic' + r'/{}.jpg'.format(i) for i in range(1, number + 1)]
task = 0
for imagePath in img_path_list:
task += 1
img2Char(imagePath, task)
''' * @breif: Synthesize images into video * @param[in]: vp -> openCV Video handle * @param[in]: number -> frames * @param[in]: savePath -> Video save path * @retval: None '''
def img2Video(vp, number, savePath):
videoFourcc = VideoWriter_fourcc(*"MP42") # Set up video encoder 
asciiImgPathList = ['cacheChar' + r'/{}.jpg'.format(i) for i in range(1, number + 1)]
asciiImgTemp = Image.open(asciiImgPathList[1]).size
videoWritter= VideoWriter(savePath, videoFourcc, vp.get(cv2.CAP_PROP_FPS), asciiImgTemp)
for imagePath in asciiImgPathList:
videoWritter.write(cv2.imread(imagePath))
videoWritter.release()
if __name__ == '__main__':
videoPath = 'test.mp4'
savePath = 'new.avi'
vp = cv2.VideoCapture(videoPath)
number = video2Pic(vp)
video2Char(number)
img2Video(vp, number, savePath)
vp.release()
 Copy code 

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved