File size: 3,922 Bytes
28dc120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import cv2
import numpy as np

from roop.typing import Frame

class Frame_Filter():
    processorname = 'generic_filter'
    type = 'frame_processor'

    plugin_options:dict = None

    c64_palette = np.array([
            [0, 0, 0],
            [255, 255, 255],
            [0x81, 0x33, 0x38],
            [0x75, 0xce, 0xc8],
            [0x8e, 0x3c, 0x97],
            [0x56, 0xac, 0x4d],
            [0x2e, 0x2c, 0x9b],
            [0xed, 0xf1, 0x71],
            [0x8e, 0x50, 0x29],
            [0x55, 0x38, 0x00],
            [0xc4, 0x6c, 0x71],
            [0x4a, 0x4a, 0x4a],
            [0x7b, 0x7b, 0x7b],
            [0xa9, 0xff, 0x9f],
            [0x70, 0x6d, 0xeb],
            [0xb2, 0xb2, 0xb2]
        ])


    def RenderC64Screen(self, image):
        # Simply round the color values to the nearest color in the palette
        image = cv2.resize(image,(320,200))
        palette = self.c64_palette / 255.0  # Normalize palette
        img_normalized = image  / 255.0  # Normalize image

        # Calculate the index in the palette that is closest to each pixel in the image
        indices = np.sqrt(((img_normalized[:, :, None, :] - palette[None, None, :, :]) ** 2).sum(axis=3)).argmin(axis=2)
        # Map the image to the palette colors
        mapped_image = palette[indices]
        return (mapped_image * 255).astype(np.uint8)  # Denormalize and return the image


    def RenderDetailEnhance(self, image):
        return cv2.detailEnhance(image)

    def RenderStylize(self, image):
        return cv2.stylization(image)
    
    def RenderPencilSketch(self, image):
        imgray, imout = cv2.pencilSketch(image, sigma_s=60, sigma_r=0.07, shade_factor=0.05)
        return imout
    
    def RenderCartoon(self, image):
        numDownSamples = 2 # number of downscaling steps
        numBilateralFilters = 7  # number of bilateral filtering steps

        img_color = image
        for _ in range(numDownSamples):
            img_color = cv2.pyrDown(img_color)
        for _ in range(numBilateralFilters):
            img_color = cv2.bilateralFilter(img_color, 9, 9, 7)
        for _ in range(numDownSamples):
            img_color = cv2.pyrUp(img_color)
        img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        img_blur = cv2.medianBlur(img_gray, 7)
        img_edge = cv2.adaptiveThreshold(img_blur, 255,
            cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 2)
        img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)
        if img_color.shape != image.shape:
            img_color = cv2.resize(img_color, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_LINEAR)        
        if img_color.shape != img_edge.shape:
            img_edge = cv2.resize(img_edge, (img_color.shape[1], img_color.shape[0]), interpolation=cv2.INTER_LINEAR)        
        return cv2.bitwise_and(img_color, img_edge)
    

    def Initialize(self, plugin_options:dict):
        if self.plugin_options is not None:
            if self.plugin_options["devicename"] != plugin_options["devicename"]:
                self.Release()
        self.plugin_options = plugin_options

    def Run(self, temp_frame: Frame) -> Frame:
        subtype = self.plugin_options["subtype"]
        if subtype == "stylize":
            return self.RenderStylize(temp_frame).astype(np.uint8)
        if subtype == "detailenhance":
            return self.RenderDetailEnhance(temp_frame).astype(np.uint8)
        if subtype == "pencil":
            return self.RenderPencilSketch(temp_frame).astype(np.uint8)
        if subtype == "cartoon":
            return self.RenderCartoon(temp_frame).astype(np.uint8)
        if subtype == "C64":
            return self.RenderC64Screen(temp_frame).astype(np.uint8)


    def Release(self):
        pass

    def getProcessedResolution(self, width, height):
        if self.plugin_options["subtype"] == "C64":
            return (320,200)
        return None