Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from PIL import Image, ImageFilter
- from collections import deque
- from time import time
- from random import randrange as rnd
- class DSU_2D:
- d = [[]]
- p = [[]]
- def __init__(self, n, m):
- self.d = [[1 for _ in range(m)] for __ in range(n)]
- self.p = [[(i, j) for j in range(m)] for i in range(n)]
- def get(self, x, y):
- if self.p[x][y] == (x, y):
- return (x, y)
- self.p[x][y] = self.get(self.p[x][y][0], self.p[x][y][1])
- return self.p[x][y]
- def uni(self, a, b):
- a = self.get(a[0], a[1])
- b = self.get(b[0], b[1])
- if a == b:
- return False
- if self.d[a[0]][a[1]] < self.d[b[0]][b[1]]:
- a, b = b, a
- self.p[b[0]][b[1]] = a
- self.d[a[0]][a[1]] += self.d[b[0]][b[1]]
- return True
- white = (255, 255, 255)
- black = (0, 0, 0)
- def Filter(num):
- name = 'C:\\Users\\bossb\\Desktop\\for_Andrew\\ (' + str(num) + ').png'
- try:
- image2 = Image.open(name).convert('RGB')
- except FileNotFoundError:
- return (0, 0, 0, 0)
- pixel_map2 = image2.load()
- w, h = image2.size[0], image2.size[1]
- pixel_map = [[pixel_map2[i, j] for j in range(h)] for i in range(w)]
- def distance(a, b, coefs):
- ans = 0
- for i in range(3):
- ans += abs(a[i] - b[i]) * coefs[i];
- return ans
- def generate_steps(dlt, flag):
- if flag:
- return [(i, j) for i in range(-dlt, dlt + 1) for j in range(-dlt, dlt + 1)]
- return [(i, j) for i in range(-dlt, dlt + 1) for j in range(-dlt, dlt + 1) if not (i == 0 and j == 0)]
- def connect(steps, border, coefs):
- dsu = DSU_2D(w, h)
- for x in range(w):
- for y in range(h):
- for (dx, dy) in steps:
- nx = x + dx
- ny = y + dy
- if nx < 0 or ny < 0 or nx >= w or ny >= h:
- continue
- if distance(pixel_map[x][y], pixel_map[nx][ny], coefs) <= border:
- dsu.uni((x, y), (nx, ny))
- return dsu
- def drawing_rule(pixel_map, w, h):
- gray = (200, 200, 200)
- for x in range(w):
- up = 0
- down = 0
- for y in range(h):
- if pixel_map[x][y] == black:
- down += 1
- for y in range(h):
- if pixel_map[x][y] == black:
- up += 1
- down -= 1
- if up > 0 and down > 0:
- pixel_map[x][y] = gray
- for x in range(w):
- for y in range(h):
- if pixel_map[x][y] == gray:
- pixel_map[x][y] = black
- def find_start_point():
- for x in range(w):
- for y in range(h):
- if distance(white, pixel_map[x][y], [1.0, 1.0, 1.0]) >= 100:
- return (x, y)
- return (w - 1, h - 1)
- def kill_grad():
- q = deque()
- q.append(find_start_point())
- used = [[False for j in range(h)] for i in range(w)]
- used[0][0] = True
- steps = generate_steps(1, False)
- while len(q):
- x, y = q.popleft()
- for (dx, dy) in steps:
- nx = x + dx
- ny = y + dy
- if nx < 0 or ny < 0 or nx >= w or ny >= h or used[nx][ny]:
- continue
- if distance(pixel_map[x][y], pixel_map[nx][ny], [1.0, 1.0, 1.0]) <= 7:
- used[nx][ny] = True
- q.append((nx, ny))
- for x in range(w):
- for y in range(h):
- if used[x][y]:
- pixel_map[x][y] = white
- kill_grad()
- for x in range(w):
- for y in range(h):
- if pixel_map[x][y] != white:
- pixel_map[x][y] = black
- steps = generate_steps(1, True)
- dsu = connect(steps, 0, [1, 1, 1])
- mp = [[0 for j in range(h)] for i in range(w)]
- for x in range(w):
- for y in range(h):
- if dsu.get(x, y) != (x, y):
- continue
- color = int(255.0 * dsu.d[x][y] / w / h)
- if color > 100:
- color = white
- else:
- color = black
- if dsu.d[x][y] < 3:
- color = white
- mp[x][y] = color
- for x in range(w):
- for y in range(h):
- a, b = dsu.get(x, y)
- pixel_map[x][y] = mp[a][b]
- drawing_rule(pixel_map, w, h)
- for x in range(w):
- for y in range(h):
- if pixel_map[x][y] == white:
- pixel_map2[x, y] = white
- steps = generate_steps(1, False)
- mp = {}
- for x in range(w):
- for y in range(h):
- good = False
- for (dx, dy) in steps:
- nx = x + dx
- ny = y + dy
- if nx < 0 or ny < 0 or nx >= w or ny >= h:
- continue
- if pixel_map2[nx, ny] == white and pixel_map2[x, y] != white:
- good = True
- break
- if good:
- if pixel_map2[x, y] not in mp:
- mp[pixel_map2[x, y]] = 0
- mp[pixel_map2[x, y]] += 1
- mx = 0
- clr = white
- border = 10
- coefs = [1.0, 1.0, 1.0]
- for val in mp:
- cur = 0
- for val2 in mp:
- if distance(val, val2, coefs) <= border:
- cur += mp[val2]
- if mx < cur:
- mx = cur
- clr = val
- for x in range(w):
- for y in range(h):
- if distance(pixel_map2[x, y], clr, [1.0, 1.0, 1.0]) <= 70:
- pixel_map2[x, y] = black
- for x in range(w):
- for y in range(h):
- if pixel_map2[x, y] != black:
- pixel_map2[x, y] = white
- return (image2, pixel_map2, w, h)
- arr = []
- W = 0
- H = 0
- def randColor():
- return (rnd(256), rnd(256), rnd(256))
- def fillWithColor(clr, mp, w, h):
- mp2 = [[mp[i, j] for j in range(h)] for i in range(w)]
- for x in range(w):
- for y in range(h):
- if mp[x, y] == black:
- for dx in range(-1, 2):
- for dy in range(-1, 2):
- if abs(dx) + abs(dy) >= 2:
- continue
- mp2[x + dx][y + dy] = black
- for x in range(w):
- for y in range(h):
- mp[x, y] = mp2[x][y]
- q = deque()
- q.append((0, 0))
- steps = [(i, j) for i in range(-1, 2) for j in range(-1, 2) if abs(i) + abs(j) == 1]
- mp[0, 0] = clr
- while len(q):
- x, y = q.popleft()
- mp[x, y] = clr
- for (dx, dy) in steps:
- nx = x + dx
- ny = y + dy
- if nx < 0 or ny < 0 or nx >= w or ny >= h or mp[nx, ny] != white:
- continue
- cnt = 0
- bad = 0
- for (dx2, dy2) in steps:
- nx2 = nx + dx2
- ny2 = ny + dy2
- if nx2 < 0 or ny2 < 0 or nx2 >= w or ny2 >= h:
- continue
- cnt += 1
- if mp[nx2, ny2] == black:
- bad += 1
- if cnt > 0 and bad / cnt >= 0.5:
- mp[nx, ny] = black
- mp[nx, ny] = clr
- q.append((nx, ny))
- for x in range(w):
- for y in range(h):
- if mp[x, y] != white:
- mp[x, y] = white
- else:
- mp[x, y] = black
- from math import *
- def findBest(a, w, h):
- arr = [a[0]]
- for (x, y) in a:
- if x == arr[-1][0]:
- continue
- else:
- arr.append([x,y])
- res = 10 ** 20
- best = (0, 0, 1)
- for freq in range(1, 100, 3):
- for amp in range(10, 40, 2):
- for ph in range(0, 360, 4):
- good = True
- phi = ph / 360 * pi
- dlts = [sin(x / freq + phi) * amp for x in range(w)]
- for (x, y) in arr:
- if y < dlts[x]:
- good = False
- break
- if not good:
- continue
- cur = 0
- for (x, y) in arr:
- cur += (y - dlts[x]) ** 2
- if cur < res:
- res = cur
- best = (amp, phi, freq)
- phi = best[1]
- amp = best[0]
- freq = best[2]
- angle = phi / pi * 360
- dlts = [sin(x / freq + phi) * amp for x in range(w)]
- print(best, angle)
- for i in range(len(a)):
- x, y = a[i]
- a[i] = (x, y - dlts[x])
- return a
- for num in range(25):
- start = time()
- im, mp, w, h = Filter(num)
- print(w, h)
- if im == 0:
- continue
- print(time() - start)
- arr2 = []
- for x in range(w):
- for y in range(h // 2):
- mp[x, y], mp[x, h - 1 - y] = mp[x, h - 1 - y], mp[x, y]
- for x in range(w):
- for y in range(h):
- if mp[x, y] == black:
- arr2.append([x, y])
- mp[x, y] = white
- mnx = arr2[0][0]
- mny = arr2[0][1]
- for val in arr2:
- mnx = min(mnx, val[0])
- mny = min(mny, val[1])
- for i in range(len(arr2)):
- arr2[i][0] -= mnx
- arr2[i][1] -= mny
- angle = 1
- for (x,y) in arr2:
- angle = min(angle, y / max(x, 1))
- for i in range(len(arr2)):
- (x, y) = arr2[i]
- arr2[i] = (x, y - angle * x)
- arr2 = findBest(arr2, w, h)
- arr2 = findBest(arr2, w, h)
- for val in arr2:
- mp[val[0], val[1]] = black
- arr2 = []
- for x in range(w):
- for y in range(h):
- if mp[x, y] == black:
- arr2.append([x, y])
- mp[x, y] = white
- mnx = arr2[0][0]
- mny = arr2[0][1]
- for val in arr2:
- mnx = min(mnx, val[0])
- mny = min(mny, val[1])
- for i in range(len(arr2)):
- arr2[i][0] -= mnx
- arr2[i][1] -= mny
- for val in arr2:
- mp[val[0], val[1]] = black
- for x in range(w):
- for y in range(h // 2):
- mp[x, y], mp[x, h - 1 - y] = mp[x, h - 1 - y], mp[x, y]
- for x in range(w):
- for y in range(h):
- if x == 0 or y == 0 or x == w - 1 or y == h - 1:
- mp[x, y] = black
- W = w
- H = h
- arr.append(mp)
- size = len(arr)
- a = int(size ** 0.5 + 0.5)
- b = (size + a - 1) // a
- result = Image.new('RGB', (W * a, H * b), color = 'white')
- pixel_map = result.load()
- for i in range(a):
- for j in range(b):
- for x in range(W):
- for y in range(H):
- if i * b + j >= size:
- break
- pixel_map[i * W + x, j * H + y] = arr[i * b + j][x, y]
- result.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement