Spaces:
Runtime error
Runtime error
| import colorsys # Polygon regions. | |
| from PIL import Image, ImageChops | |
| from pprint import pprint | |
| import cv2 # Polygon regions. | |
| import numpy as np | |
| import PIL | |
| import torch | |
| SPLROW = ";" | |
| SPLCOL = "," | |
| KEYROW = "ADDROW" | |
| KEYCOL = "ADDCOL" | |
| KEYBASE = "ADDBASE" | |
| KEYCOMM = "ADDCOMM" | |
| KEYBRK = "BREAK" | |
| NLN = "\n" | |
| DKEYINOUT = { # Out/in, horizontal/vertical or row/col first. | |
| ("out",False): KEYROW, | |
| ("in",False): KEYCOL, | |
| ("out",True): KEYCOL, | |
| ("in",True): KEYROW, | |
| } | |
| fidentity = lambda x: x | |
| ffloatd = lambda c: (lambda x: floatdef(x,c)) | |
| fspace = lambda x: " {} ".format(x) | |
| fcountbrk = lambda x: x.count(KEYBRK) | |
| fint = lambda x: int(x) | |
| def floatdef(x, vdef): | |
| """Attempt conversion to float, use default value on error. | |
| Mainly for empty ratios, double commas. | |
| """ | |
| try: | |
| return float(x) | |
| except ValueError: | |
| print("'{}' is not a number, converted to {}".format(x,vdef)) | |
| return vdef | |
| class Region(): | |
| """Specific Region used to split a layer to single prompts.""" | |
| def __init__(self, st, ed, base, breaks): | |
| """Range with start and end values, base weight and breaks count for context splitting.""" | |
| self.start = st # Range for the cell (cols only). | |
| self.end = ed | |
| self.base = base # How much of the base prompt is applied (difference). | |
| self.breaks = breaks # How many unrelated breaks the prompt contains. | |
| class Row(): | |
| """Row containing cell refs and its own ratio range.""" | |
| def __init__(self, st, ed, cols): | |
| """Range with start and end values, base weight and breaks count for context splitting.""" | |
| self.start = st # Range for the row. | |
| self.end = ed | |
| self.cols = cols # List of cells. | |
| def is_l2(l): | |
| return isinstance(l[0],list) | |
| def l2_count(l): | |
| cnt = 0 | |
| for row in l: | |
| cnt + cnt + len(row) | |
| return cnt | |
| def list_percentify(l): | |
| """ | |
| Convert each row in L2 to relative part of 100%. | |
| Also works on L1, applying once globally. | |
| """ | |
| lret = [] | |
| if is_l2(l): | |
| for row in l: | |
| # row2 = [float(v) for v in row] | |
| row2 = [v / sum(row) for v in row] | |
| lret.append(row2) | |
| else: | |
| row = l[:] | |
| # row2 = [float(v) for v in row] | |
| row2 = [v / sum(row) for v in row] | |
| lret = row2 | |
| return lret | |
| def list_cumsum(l): | |
| """ | |
| Apply cumsum to L2 per row, ie newl[n] = l[0:n].sum . | |
| Works with L1. | |
| Actually edits l inplace, idc. | |
| """ | |
| lret = [] | |
| if is_l2(l): | |
| for row in l: | |
| for (i,v) in enumerate(row): | |
| if i > 0: | |
| row[i] = v + row[i - 1] | |
| lret.append(row) | |
| else: | |
| row = l[:] | |
| for (i,v) in enumerate(row): | |
| if i > 0: | |
| row[i] = v + row[i - 1] | |
| lret = row | |
| return lret | |
| def list_rangify(l): | |
| """ | |
| Merge every 2 elems in L2 to a range, starting from 0. | |
| """ | |
| lret = [] | |
| if is_l2(l): | |
| for row in l: | |
| row2 = [0] + row | |
| row3 = [] | |
| for i in range(len(row2) - 1): | |
| row3.append([row2[i],row2[i + 1]]) | |
| lret.append(row3) | |
| else: | |
| row2 = [0] + l | |
| row3 = [] | |
| for i in range(len(row2) - 1): | |
| row3.append([row2[i],row2[i + 1]]) | |
| lret = row3 | |
| return lret | |
| def ratiosdealer(split_ratio2,split_ratio2r): | |
| split_ratio2 = list_percentify(split_ratio2) | |
| split_ratio2 = list_cumsum(split_ratio2) | |
| split_ratio2 = list_rangify(split_ratio2) | |
| split_ratio2r = list_percentify(split_ratio2r) | |
| split_ratio2r = list_cumsum(split_ratio2r) | |
| split_ratio2r = list_rangify(split_ratio2r) | |
| return split_ratio2,split_ratio2r | |
| def round_dim(x,y): | |
| """Return division of two numbers, rounding 0.5 up. | |
| Seems that dimensions which are exactly 0.5 are rounded up - see 680x488, second iter. | |
| A simple mod check should get the job done. | |
| If not, can always brute force the divisor with +-1 on each of h/w. | |
| """ | |
| return x // y + (x % y >= y // 2) | |
| def keyconverter(self,split_ratio,usebase): | |
| '''convert BREAKS to ADDCOMM/ADDBASE/ADDCOL/ADDROW''' | |
| if SPLROW not in split_ratio: # Commas only - interpret as 1d. | |
| split_ratio2 = split_l2(split_ratio, SPLROW, SPLCOL, map_function = ffloatd(1)) | |
| split_ratio2r = [1] | |
| else: | |
| (split_ratio2r,split_ratio2) = split_l2(split_ratio, SPLROW, SPLCOL, | |
| indsingles = True, map_function = ffloatd(1)) | |
| (split_ratio2,split_ratio2r) = ratiosdealer(split_ratio2,split_ratio2r) | |
| #print(keychanger,p.prompt) | |
| txtkey = fspace(DKEYINOUT[("in", False)]) + NLN | |
| lkeys = [txtkey.join([""] * len(cell)) for cell in split_ratio2] | |
| txtkey = fspace(DKEYINOUT[("out", False)]) + NLN | |
| template = txtkey.join(lkeys) | |
| if usebase: | |
| template = fspace(KEYBASE) + NLN + template | |
| changer = template.split(NLN) | |
| changer = [l.strip() for l in changer] | |
| keychanger=changer[:-1] | |
| for change in keychanger: | |
| if change == KEYBASE and KEYBASE in self.SR_prompt: continue | |
| self.SR_prompt= self.SR_prompt.replace(KEYBRK,change,1) | |
| def split_l2(s, key_row, key_col, indsingles = False, map_function = fidentity, split_struct = None): | |
| lret = [] | |
| if split_struct is None: | |
| lrows = s.split(key_row) | |
| lrows = [row.split(key_col) for row in lrows] | |
| # print(lrows) | |
| for r in lrows: | |
| cell = [map_function(x) for x in r] | |
| lret.append(cell) | |
| if indsingles: | |
| lsingles = [row[0] for row in lret] | |
| lcells = [row[1:] if len(row) > 1 else row for row in lret] | |
| lret = (lsingles,lcells) | |
| else: | |
| lrows = str(s).split(key_row) | |
| r = 0 | |
| lcells = [] | |
| lsingles = [] | |
| vlast = 1 | |
| for row in lrows: | |
| row2 = row.split(key_col) | |
| row2 = [map_function(x) for x in row2] | |
| vlast = row2[-1] | |
| indstop = False | |
| while not indstop: | |
| if (r >= len(split_struct) # Too many cell values, ignore. | |
| or (len(row2) == 0 and len(split_struct) > 0)): # Cell exhausted. | |
| indstop = True | |
| if not indstop: | |
| if indsingles: # Singles split. | |
| lsingles.append(row2[0]) # Row ratio. | |
| if len(row2) > 1: | |
| row2 = row2[1:] | |
| if len(split_struct[r]) >= len(row2): # Repeat last value. | |
| indstop = True | |
| broadrow = row2 + [row2[-1]] * (len(split_struct[r]) - len(row2)) | |
| r = r + 1 | |
| lcells.append(broadrow) | |
| else: # Overfilled this row, cut and move to next. | |
| broadrow = row2[:len(split_struct[r])] | |
| row2 = row2[len(split_struct[r]):] | |
| r = r + 1 | |
| lcells.append(broadrow) | |
| # If not enough new rows, repeat the last one for entire base, preserving structure. | |
| cur = len(lcells) | |
| while cur < len(split_struct): | |
| lcells.append([vlast] * len(split_struct[cur])) | |
| cur = cur + 1 | |
| lret = lcells | |
| if indsingles: | |
| lsingles = lsingles + [lsingles[-1]] * (len(split_struct) - len(lsingles)) | |
| lret = (lsingles,lcells) | |
| return lret | |
| def matrixdealer(self, split_ratio, baseratio): | |
| # print(split_ratio, baseratio) | |
| prompt = self.SR_prompt | |
| if KEYBASE in prompt: prompt = prompt.split(KEYBASE,1)[1] | |
| if (KEYCOL in prompt.upper() or KEYROW in prompt.upper()): | |
| # breaks = prompt.count(KEYROW) + prompt.count(KEYCOL) + int(self.usebase) | |
| # Prompt anchors, count breaks between special keywords. | |
| # print('prompt:', prompt) | |
| lbreaks = split_l2(prompt, KEYROW, KEYCOL, map_function = fcountbrk) | |
| # print('lbreaks', lbreaks) | |
| if (SPLROW not in split_ratio and (KEYROW in prompt.upper()) != (KEYCOL in prompt.upper())): | |
| # By popular demand, 1d integrated into 2d. | |
| # This works by either adding a single row value (inner), | |
| # or setting flip to the reverse (outer). | |
| # Only applies when using just ADDROW / ADDCOL keys, and commas in ratio. | |
| split_ratio = "1" + SPLCOL + split_ratio | |
| (split_ratio2r,split_ratio2) = split_l2(split_ratio, SPLROW, SPLCOL, indsingles = True, | |
| map_function = ffloatd(1), split_struct = lbreaks) | |
| else: # Standard ratios, split to rows and cols. | |
| (split_ratio2r,split_ratio2) = split_l2(split_ratio, SPLROW, SPLCOL, indsingles = True, | |
| map_function = ffloatd(1), split_struct = lbreaks) | |
| # print('split_ratio2r', split_ratio2r) | |
| # print('split_ratio2', split_ratio2) | |
| # More like "bweights", applied per cell only. | |
| baseratio2 = split_l2(baseratio, SPLROW, SPLCOL, map_function = ffloatd(0), split_struct = lbreaks) | |
| # print(baseratio2) | |
| (split_ratio,split_ratior) = ratiosdealer(split_ratio2,split_ratio2r) | |
| baseratio = baseratio2 | |
| # Merge various L2s to cells and rows. | |
| drows = [] | |
| for r,_ in enumerate(lbreaks): | |
| dcells = [] | |
| for c,_ in enumerate(lbreaks[r]): | |
| d = Region(split_ratio[r][c][0], split_ratio[r][c][1], baseratio[r][c], lbreaks[r][c]) | |
| dcells.append(d) | |
| drow = Row(split_ratior[r][0], split_ratior[r][1], dcells) | |
| drows.append(drow) | |
| self.split_ratio = drows | |
| self.baseratio = baseratio | |
| # class test: | |
| # def __init__(self, prompt,split_ratio=None,baseratio=0.2,usebase=False): | |
| # self.prompt = prompt | |
| # self.split_ratio = split_ratio | |
| # self.baseratio = 0.2 | |
| # self.usebase = usebase | |
| # test_prompt='a girl BREAK a cute boy BREAK a dog BREAK a tree.' | |
| # split_ratio='1,1,1;1,1,1' | |
| # x=test(test_prompt,split_ratio) | |
| # keyconverter(x,split_ratio,usebase=False) | |
| # print(x.prompt) | |
| # matrixdealer(x, split_ratio, 0.2) |