Skip to content

Latest commit

 

History

History
310 lines (258 loc) · 7.52 KB

632-1189958-补间插值效果.sy.md

File metadata and controls

310 lines (258 loc) · 7.52 KB
show version enable_checker
step
1.0
true

opencv

回忆

  • 上次制作了动图gif
  • 可以设置
    • fps
    • duration
    • loop
  • 以前的动画
    • 应该都可以保存成动图了
  • 动画还有什么好玩的吗?

持续绘画圆形

import numpy as np    
import cv2       
import time      
width =  600 
height = 300 
x = 100         
y = 200         
img = np.ones((height, width, 3),np.uint8) * 255 
                 
while cv2.waitKey(1) == -1: 
    cv2.circle(img, (x,y), 30 ,(0,255,0),-1)
    cv2.imshow("img",img) 
    time.sleep(1/100)    
    x = x + 1                                                                 
cv2.destroyAllWindows()
  • 中间的圆形是匀速移动的

图片描述

  • 可以每次只有一个圆形吗?

匀速移动的圆形

import numpy as np
import cv2
import time
width =  600
height = 300
x = 100
y = 200
     
while cv2.waitKey(1) == -1:
    img = np.ones((height, width, 3),np.uint8) * 255                          
    cv2.circle(img, (x,y), 30 ,(0,255,0),-1)
    cv2.imshow("img",img)
    time.sleep(1/100)
    x = x + 1
cv2.destroyAllWindows()
  • 出现了
    • 一个匀速直线运动的圆形

图片描述

匀速直线运动的补间

import numpy as np    
import cv2            
import time           
width =  600          
height = 300          
x = 100               
y = 200               
                      
def linear(current_frame,start_frame,end_frame,start_value,end_value):
    if current_frame<start_frame:
        return start_value
    elif current_frame>end_frame:
        return end_value
    tan = (end_value-start_value)/(end_frame-start_frame)
    result = start_value + tan * (current_frame-start_frame)
    return int(result)                                                         
                      
frame = 0             
while cv2.waitKey(1) == -1:
    start_frame = 60  
    end_frame = 120   
    start_x = 100     
    end_x = 400       
    x = linear(frame,start_frame,end_frame,start_x,end_x)
    img = np.ones((height, width, 3),np.uint8) * 255
    cv2.circle(img, (x,y), 30 ,(0,255,0),-1)
    cv2.imshow("img",img)
    time.sleep(1/30)  
    frame += 1        
cv2.destroyAllWindows()
  • 设置了一个线性插值算法,通过
    • 开始时间
    • 结束时间
    • 开始位置
    • 结束位置
  • 完成时间和空间上的控制

图片描述

  • 可以把线性插值插值
    • 变成缓动插值吗?
  • 什么是缓动插值呢?

缓动

firefox https://cubic-bezier.com
  • 原始的运动是匀速直线

图片描述

  • 可以修改为缓动曲线
  • 有什么样的缓动曲线呢?

缓动曲线

firefox https://easings.net/#

图片描述

  • 缓动无处不在

图片描述

  • 我们试试easeInOutQuad

缓动曲线

def easeInOutQuad(current_frame,start_frame,end_frame,start_value,end_value):
    if current_frame<start_frame:
        return start_value
    elif current_frame>end_frame:
        return end_value
    ratio =  (current_frame-start_frame)/(end_frame-start_frame)
    if ratio < 0.5:
        tan  = 2 * ratio * ratio
    else:
        tan =  1 - pow(-2 * ratio + 2, 2) / 2
    result = start_value + tan * (end_value-start_value)
    return int(result)
    
import numpy as np    
import cv2            
import time           
width =  600          
height = 300          
x = 100               
y = 200
frame = 0             
while cv2.waitKey(1) == -1:
    start_frame = 60  
    end_frame = 120   
    start_x = 100     
    end_x = 400       
    x = easeInOutQuad(frame,start_frame,end_frame,start_x,end_x)
    img = np.ones((height, width, 3),np.uint8) * 255
    cv2.circle(img, (x,y), 30 ,(0,255,0),-1)
    cv2.imshow("img",img)
    time.sleep(1/30)  
    frame += 1        
cv2.destroyAllWindows()
  • 可以观察到
    • 缓动在时间上的区别
  • 可以两个放在一起对比吗?

对比效果

def linear(current_frame,start_frame,end_frame,start_value,end_value):
    if current_frame<start_frame:
        return start_value
    elif current_frame>end_frame:
        return end_value
    tan = (end_value-start_value)/(end_frame-start_frame)
    result = start_value + tan * (current_frame-start_frame)
    return int(result)

def easeInOutQuad(current_frame,start_frame,end_frame,start_value,end_value):
    if current_frame<start_frame:
        return start_value
    elif current_frame>end_frame:
        return end_value
    ratio =  (current_frame-start_frame)/(end_frame-start_frame)
    if ratio < 0.5:
        tan  = 2 * ratio * ratio
    else:
        tan =  1 - pow(-2 * ratio + 2, 2) / 2
    result = start_value + tan * (end_value-start_value)
    return int(result)

import numpy as np
import cv2
import time
width =  600
height = 300
y_red = 200
y_green = 100

frame = 0
while cv2.waitKey(1) == -1:
    start_frame = 60
    end_frame = 120
    start_x = 100
    end_x = 400
    x = easeInOutQuad(frame,start_frame,end_frame,start_x,end_x)
    img = np.ones((height, width, 3),np.uint8) * 255
    cv2.circle(img, (x,y_green), 30 ,(0,255,0),-1)
    x = linear(frame,start_frame,end_frame,start_x,end_x)
    cv2.circle(img, (x,y_red), 30 ,(0,0,255),-1)
    cv2.imshow("img",img)
    time.sleep(1/30)
    frame += 1
cv2.destroyAllWindows()
  • 效果

图片描述

  • 可以做出
    • 细胞呼吸的效果吗?

呼吸的效果

import math               
import numpy as np        
import cv2                
import time               
width = height = 300      
x = y = 150               
r = 0                     
isBigger = True           
num = 0                   
                          
while cv2.waitKey(1) == -1:
    num = num + 1         
    r = int(math.cos(num/30) * 50 + 60)
    img = np.ones((width, height, 3),np.uint8) * 255
    cv2.circle(img, (x,y), r ,(0,255,0),-1)
    cv2.imshow("img",img) 
    time.sleep(1/100)     
cv2.destroyAllWindows()
  • 效果

图片描述

细胞呼吸效果

import cv2 
import time
import numpy as np
import math
width = height = 300 
x = y = 150 
r = 0 
isBigger = True
num = 0 
        
while cv2.waitKey(1) == -1: 
    img = np.zeros((width, height, 3),np.uint8) * 255 
    num = num + 1 
    r = int(math.cos(num/30) * 20 + 50) 
    color1 = (200,200,50)
    color2 = (50,50,200)
    color_b = int((math.cos(num/30)*(color2[0]-color1[0])+(color2[0]+color1[0]))*0.5 )
    color_g = int((math.cos(num/30)*(color2[1]-color1[1])+(color2[1]+color1[1]))*0.5 )
    color_r = int((math.cos(num/30)*(color2[2]-color1[2])+(color2[2]+color1[2]))*0.5 )
    color = (color_b,color_g,color_r)
    y = 150 - int(math.cos(num/30)*30)
    cv2.circle(img, (x,y), r ,color,-1)
    cv2.imshow("img",img)
    time.sleep(1/100)
cv2.destroyAllWindows()
  • 效果

图片描述

  • 可以把这个效果做成循环gif吗?

总结 🤔

  • 这次研究了 动画过程的细节
    • 缓动 ease
    • 可以有 缓入和缓出
    • 可有二次、余弦等缓入公式
  • 可以把动画效果保存成视频文件吗?🤔
  • 下次再说👋