File size: 2,980 Bytes
d77c815
 
 
 
 
 
 
aba8c4f
d77c815
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import numpy as np
import cv2
import numexpr
import re
import torch
from PIL import Image

def parse_weight_schedule(string, max_frames):
    string = re.sub(r'\s+', '', str(string))
    keyframes = {}
    parts = string.split(',')
    
    for part in parts:
        try:
            if ':' not in part: continue
            f_str, v_str = part.split(':', 1)
            keyframes[int(f_str)] = v_str.strip('()')
        except: continue
        
    if 0 not in keyframes: keyframes[0] = "0"
    
    series = np.zeros(int(max_frames))
    sorted_keys = sorted(keyframes.keys())
    
    for i in range(len(sorted_keys)):
        f_start = sorted_keys[i]
        f_end = sorted_keys[i+1] if i < len(sorted_keys)-1 else int(max_frames)
        formula = keyframes[f_start]
        
        for f in range(f_start, f_end):
            t = f
            try:
                val = numexpr.evaluate(formula, local_dict={'t':t, 'pi':np.pi, 'sin':np.sin, 'cos':np.cos})
                series[f] = float(val)
            except:
                try: series[f] = float(formula)
                except: series[f] = series[f-1] if f > 0 else 0.0
    return series

def get_border_mode(mode_str):
    return {'Reflect': cv2.BORDER_REFLECT_101, 'Replicate': cv2.BORDER_REPLICATE, 'Wrap': cv2.BORDER_WRAP, 'Black': cv2.BORDER_CONSTANT}.get(mode_str, cv2.BORDER_REFLECT_101)

def maintain_colors(image, anchor, mode='LAB'):
    if mode == 'None' or anchor is None: return image
    img_np = np.array(image).astype(np.uint8)
    anc_np = np.array(anchor).astype(np.uint8)
    
    if mode == 'LAB':
        img_cvt = cv2.cvtColor(img_np, cv2.COLOR_RGB2LAB)
        anc_cvt = cv2.cvtColor(anc_np, cv2.COLOR_RGB2LAB)
        for i in range(3):
            img_cvt[:,:,i] = np.clip(img_cvt[:,:,i] - img_cvt[:,:,i].mean() + anc_cvt[:,:,i].mean(), 0, 255)
        return Image.fromarray(cv2.cvtColor(img_cvt, cv2.COLOR_LAB2RGB))
    elif mode == 'HSV':
        img_cvt = cv2.cvtColor(img_np, cv2.COLOR_RGB2HSV)
        anc_cvt = cv2.cvtColor(anc_np, cv2.COLOR_RGB2HSV)
        for i in [1, 2]:
            img_cvt[:,:,i] = np.clip(img_cvt[:,:,i] - img_cvt[:,:,i].mean() + anc_cvt[:,:,i].mean(), 0, 255)
        return Image.fromarray(cv2.cvtColor(img_cvt, cv2.COLOR_HSV2RGB))
    return image

def anim_frame_warp_2d(prev_img, args, border_mode):
    if prev_img is None: return None
    cv_img = np.array(prev_img)
    h, w = cv_img.shape[:2]
    center = (w // 2, h // 2)
    mat = cv2.getRotationMatrix2D(center, args.get('angle',0), args.get('zoom',1))
    mat[0, 2] += args.get('tx',0); mat[1, 2] += args.get('ty',0)
    return Image.fromarray(cv2.warpAffine(cv_img, mat, (w, h), borderMode=get_border_mode(border_mode)))

def add_noise(img, noise_amt):
    if noise_amt <= 0: return img
    img_np = np.array(img).astype(np.float32)
    noise = np.random.normal(0, noise_amt * 255, img_np.shape).astype(np.float32)
    return Image.fromarray(np.clip(img_np + noise, 0, 255).astype(np.uint8))