Skip to content

Class Definitions

TenteEEEE edited this page Jul 25, 2020 · 3 revisions

Main structure

To define a conversion model, we must inheritance Base Classes.
There are 4 base classes, Converter, Loader, Patcher, and Model Manager.

Probably, Quiche's code is simplest and easy to understand from codes.

from base_class import *
from util import improc
import numpy as np
from PIL import Image

# Converter Class
class img_converter(converter):
    def __init__(self, options=[]):
        super().__init__(options)

    def convert(self, image):
        return improc.resize(image, [.5, .5])


basesize = 2048
patchers = dict.fromkeys(['face'])

# Patcher and Loader Class
patchers['face'] = {
    'cheek': [patcher(loader('cheek'), img_converter(), [150, 1100], basesize=basesize)],
    'eye_brow': [patcher(loader('eye_brow'), img_converter(), [475, 0], basesize=basesize)],
    'eye_line': [patcher(loader('eye_line'), img_converter(), [475, 117], basesize=basesize)],
    'eye_shadow': [patcher(loader('eye_shadow'), img_converter(), [300, 893], basesize=basesize)],
    'lip': [patcher(loader('lip'), img_converter(), [875, 1550], basesize=basesize)],
}

# Model Manager Class
manager = model_manager(model='quiche', displayname='キッシュ', patchers=patchers, options={})

Converter

Converter is the main part of conversion programs. You should write down all the conversion code using this class.
The input is PIL's image data. The output also must return PIL image data.
Here is an example of Quiche model. It just resizes the texture.

class img_converter(converter):
    def __init__(self, options=[]):
        super().__init__(options)

    def convert(self, image):
        return improc.resize(image, [.5, .5])

Loader

Here we define an image loader for the converter. The base directory is Material.
When you want to load 'cheek' images,

loader('cheek')

Very simple, right?

Patcher

Patcher consists of Converter and Loader objects. Normally, we just define a normalized position.
Do not worry. Patcher class calculates the normalized position automatically when you set correct texture size(basesize).

patcher(loader('cheek'), img_converter(), [150, 1100], basesize=basesize) # Quiche's body texture size is 2048px, so basesize is 2048

[150(Row), 1100(Col)] is the patching position. You can check it with some painting software.

Model Manager

Model Manager handles a dictionary of Patcher objects.
Patcher dictionary's key name must be the same as the texture(part) name of the model.

patchers['face'] = {
    'cheek': [patcher(loader('cheek'), img_converter(), [150, 1100], basesize=basesize)],
    'eye_brow': [patcher(loader('eye_brow'), img_converter(), [475, 0], basesize=basesize)],
    'eye_line': [patcher(loader('eye_line'), img_converter(), [475, 117], basesize=basesize)],
    'eye_shadow': [patcher(loader('eye_shadow'), img_converter(), [300, 893], basesize=basesize)],
    'lip': [patcher(loader('lip'), img_converter(), [875, 1550], basesize=basesize)],
}

Here we defined that "Quiche's face part can patch 'cheek', 'eye_brow', 'eye_line', 'eye_shadown', and 'lip' components".
After making patcher dictionaly, you just define the model manager object.
Displayname will be used for REST API.

manager = model_manager(model='quiche', displayname='キッシュ', patchers=patchers, options={})

Any Questions?

Ask @tenteeee_vrc.
Discord is TenteEEEE#8378.