Advertisement
999ms

captcha filter vers 2

Apr 1st, 2020
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.90 KB | None | 0 0
  1. from PIL import Image, ImageFilter
  2. from collections import deque
  3. from time import time
  4. from random import randrange as rnd
  5.  
  6. class DSU_2D:
  7.     d = [[]]
  8.     p = [[]]
  9.     def __init__(self, n, m):
  10.         self.d = [[1 for _ in range(m)] for __ in range(n)]
  11.         self.p = [[(i, j) for j in range(m)] for i in range(n)]
  12.    
  13.     def get(self, x, y):
  14.         if self.p[x][y] == (x, y):
  15.             return (x, y)
  16.         self.p[x][y] = self.get(self.p[x][y][0], self.p[x][y][1])
  17.         return self.p[x][y]
  18.    
  19.     def uni(self, a, b):
  20.         a = self.get(a[0], a[1])
  21.         b = self.get(b[0], b[1])
  22.         if a == b:
  23.             return False
  24.         if self.d[a[0]][a[1]] < self.d[b[0]][b[1]]:
  25.             a, b = b, a
  26.         self.p[b[0]][b[1]] = a
  27.         self.d[a[0]][a[1]] += self.d[b[0]][b[1]]
  28.         return True
  29.  
  30.  
  31. white = (255, 255, 255)
  32. black = (0, 0, 0)
  33.    
  34. def Filter(num):
  35.     name = 'C:\\Users\\bossb\\Desktop\\for_Andrew\\  (' + str(num) + ').png'
  36.     try:  
  37.         image2 = Image.open(name).convert('RGB')
  38.     except FileNotFoundError:  
  39.         return (0, 0, 0, 0)
  40.     pixel_map2 = image2.load()
  41.     w, h = image2.size[0], image2.size[1]
  42.     pixel_map = [[pixel_map2[i, j] for j in range(h)] for i in range(w)]
  43.    
  44.     def distance(a, b, coefs):
  45.         ans = 0
  46.         for i in range(3):
  47.             ans += abs(a[i] - b[i]) * coefs[i];
  48.         return ans
  49.    
  50.    
  51.     def generate_steps(dlt, flag):
  52.         if flag:
  53.             return [(i, j) for i in range(-dlt, dlt + 1) for j in range(-dlt, dlt + 1)]  
  54.         return [(i, j) for i in range(-dlt, dlt + 1) for j in range(-dlt, dlt + 1) if not (i == 0 and j == 0)]
  55.    
  56.     def connect(steps, border, coefs):
  57.         dsu = DSU_2D(w, h)
  58.        
  59.         for x in range(w):
  60.             for y in range(h):
  61.                 for (dx, dy) in steps:
  62.                     nx = x + dx
  63.                     ny = y + dy
  64.                     if nx < 0 or ny < 0 or nx >= w or ny >= h:
  65.                         continue
  66.                     if distance(pixel_map[x][y], pixel_map[nx][ny], coefs) <= border:
  67.                         dsu.uni((x, y), (nx, ny))
  68.         return dsu
  69.    
  70.     def drawing_rule(pixel_map, w, h):
  71.         gray = (200, 200, 200)
  72.         for x in range(w):
  73.             up = 0
  74.             down = 0
  75.             for y in range(h):
  76.                 if pixel_map[x][y] == black:
  77.                     down += 1
  78.             for y in range(h):
  79.                 if pixel_map[x][y] == black:
  80.                     up += 1
  81.                     down -= 1
  82.                 if up > 0 and down > 0:
  83.                     pixel_map[x][y] = gray
  84.         for x in range(w):
  85.             for y in range(h):
  86.                 if pixel_map[x][y] == gray:
  87.                     pixel_map[x][y] = black
  88.    
  89.    
  90.     def find_start_point():
  91.         for x in range(w):
  92.             for y in range(h):
  93.                 if distance(white, pixel_map[x][y], [1.0, 1.0, 1.0]) >= 100:
  94.                     return (x, y)
  95.         return (w - 1, h - 1)
  96.    
  97.     def kill_grad():
  98.         q = deque()
  99.         q.append(find_start_point())
  100.         used = [[False for j in range(h)] for i in range(w)]
  101.         used[0][0] = True
  102.         steps = generate_steps(1, False)
  103.         while len(q):
  104.             x, y = q.popleft()
  105.             for (dx, dy) in steps:
  106.                 nx = x + dx
  107.                 ny = y + dy
  108.                 if nx < 0 or ny < 0 or nx >= w or ny >= h or used[nx][ny]:
  109.                     continue
  110.                 if distance(pixel_map[x][y], pixel_map[nx][ny], [1.0, 1.0, 1.0]) <= 7:
  111.                     used[nx][ny] = True
  112.                     q.append((nx, ny))
  113.         for x in range(w):
  114.             for y in range(h):
  115.                 if used[x][y]:
  116.                     pixel_map[x][y] = white
  117.    
  118.     kill_grad()
  119.    
  120.     for x in range(w):
  121.         for y in range(h):
  122.             if pixel_map[x][y] != white:
  123.                 pixel_map[x][y] = black
  124.    
  125.     steps = generate_steps(1, True)
  126.     dsu = connect(steps, 0, [1, 1, 1])
  127.     mp = [[0 for j in range(h)] for i in range(w)]
  128.  
  129.     for x in range(w):
  130.         for y in range(h):
  131.             if dsu.get(x, y) != (x, y):
  132.                 continue
  133.             color = int(255.0 * dsu.d[x][y] / w / h)
  134.             if color > 100:
  135.                 color = white
  136.             else:
  137.                 color = black
  138.             if dsu.d[x][y] < 3:
  139.                 color = white
  140.             mp[x][y] = color
  141.            
  142.     for x in range(w):
  143.         for y in range(h):
  144.             a, b = dsu.get(x, y)
  145.             pixel_map[x][y] = mp[a][b]
  146.    
  147.     drawing_rule(pixel_map, w, h)
  148.    
  149.     for x in range(w):
  150.         for y in range(h):
  151.             if pixel_map[x][y] == white:
  152.                 pixel_map2[x, y] = white
  153.        
  154.     steps = generate_steps(1, False)
  155.     mp = {}
  156.    
  157.     for x in range(w):
  158.         for y in range(h):
  159.             good = False
  160.             for (dx, dy) in steps:
  161.                 nx = x + dx
  162.                 ny = y + dy
  163.                 if nx < 0 or ny < 0 or nx >= w or ny >= h:
  164.                     continue
  165.                 if pixel_map2[nx, ny] == white and pixel_map2[x, y] != white:
  166.                     good = True
  167.                     break
  168.             if good:
  169.                 if pixel_map2[x, y] not in mp:
  170.                     mp[pixel_map2[x, y]] = 0
  171.                 mp[pixel_map2[x, y]] += 1
  172.    
  173.     mx = 0
  174.     clr = white
  175.     border = 10
  176.     coefs = [1.0, 1.0, 1.0]
  177.    
  178.     for val in mp:
  179.         cur = 0
  180.         for val2 in mp:
  181.             if distance(val, val2, coefs) <= border:
  182.                 cur += mp[val2]
  183.         if mx < cur:
  184.             mx = cur
  185.             clr = val
  186.  
  187.     for x in range(w):
  188.         for y in range(h):
  189.             if distance(pixel_map2[x, y], clr, [1.0, 1.0, 1.0]) <= 70:
  190.                 pixel_map2[x, y] = black
  191.    
  192.     for x in range(w):
  193.         for y in range(h):
  194.             if pixel_map2[x, y] != black:
  195.                 pixel_map2[x, y] = white
  196.     return (image2, pixel_map2, w, h)
  197.    
  198. arr = []
  199. W = 0
  200. H = 0
  201.  
  202. def randColor():
  203.     return (rnd(256), rnd(256), rnd(256))
  204.  
  205. def fillWithColor(clr, mp, w, h):
  206.     mp2 = [[mp[i, j] for j in range(h)] for i in range(w)]
  207.     for x in range(w):
  208.         for y in range(h):
  209.             if mp[x, y] == black:
  210.                 for dx in range(-1, 2):
  211.                     for dy in range(-1, 2):
  212.                         if abs(dx) + abs(dy) >= 2:
  213.                             continue
  214.                         mp2[x + dx][y + dy] = black
  215.     for x in range(w):
  216.         for y in range(h):
  217.             mp[x, y] = mp2[x][y]
  218.     q = deque()
  219.     q.append((0, 0))
  220.     steps = [(i, j) for i in range(-1, 2) for j in range(-1, 2) if abs(i) + abs(j) == 1]
  221.     mp[0, 0] = clr
  222.     while len(q):
  223.         x, y = q.popleft()
  224.         mp[x, y] = clr
  225.         for (dx, dy) in steps:
  226.             nx = x + dx
  227.             ny = y + dy
  228.             if nx < 0 or ny < 0 or nx >= w or ny >= h or mp[nx, ny] != white:
  229.                 continue
  230.             cnt = 0
  231.             bad = 0
  232.             for (dx2, dy2) in steps:
  233.                 nx2 = nx + dx2
  234.                 ny2 = ny + dy2
  235.                 if nx2 < 0 or ny2 < 0 or nx2 >= w or ny2 >= h:
  236.                     continue
  237.                 cnt += 1
  238.                 if mp[nx2, ny2] == black:
  239.                     bad += 1
  240.             if cnt > 0 and bad / cnt >= 0.5:
  241.                 mp[nx, ny] = black
  242.             mp[nx, ny] = clr
  243.             q.append((nx, ny))
  244.            
  245.     for x in range(w):
  246.         for y in range(h):
  247.             if mp[x, y] != white:
  248.                 mp[x, y] = white
  249.             else:
  250.                 mp[x, y] = black
  251.  
  252. from math import *
  253.  
  254.  
  255. def findBest(a, w, h):
  256.     arr = [a[0]]
  257.     for (x, y) in a:
  258.         if x == arr[-1][0]:
  259.             continue
  260.         else:
  261.             arr.append([x,y])
  262.     res = 10 ** 20
  263.     best = (0, 0, 1)
  264.     for freq in range(1, 100, 3):
  265.         for amp in range(10, 40, 2):
  266.             for ph in range(0, 360, 4):
  267.                 good = True
  268.                 phi = ph / 360 * pi
  269.                 dlts = [sin(x / freq + phi) * amp for x in range(w)]
  270.                 for (x, y) in arr:
  271.                     if y < dlts[x]:
  272.                         good = False
  273.                         break
  274.                 if not good:
  275.                     continue
  276.                 cur = 0
  277.                 for (x, y) in arr:
  278.                     cur += (y - dlts[x]) ** 2
  279.                 if cur < res:
  280.                     res = cur
  281.                     best = (amp, phi, freq)
  282.     phi = best[1]
  283.     amp = best[0]
  284.     freq = best[2]
  285.     angle = phi / pi * 360
  286.     dlts = [sin(x / freq + phi) * amp for x in range(w)]
  287.     print(best, angle)
  288.     for i in range(len(a)):
  289.         x, y = a[i]
  290.         a[i] = (x, y - dlts[x])
  291.     return a
  292.    
  293. for num in range(25):
  294.     start = time()
  295.     im, mp, w, h = Filter(num)
  296.     print(w, h)
  297.     if im == 0:
  298.         continue
  299.     print(time() - start)
  300.    
  301.     arr2 = []
  302.     for x in range(w):
  303.         for y in range(h // 2):
  304.             mp[x, y], mp[x, h - 1 - y] = mp[x, h - 1 - y], mp[x, y]
  305.     for x in range(w):
  306.         for y in range(h):
  307.             if mp[x, y] == black:
  308.                 arr2.append([x, y])
  309.                 mp[x, y] = white
  310.     mnx = arr2[0][0]
  311.     mny = arr2[0][1]
  312.     for val in arr2:
  313.         mnx = min(mnx, val[0])
  314.         mny = min(mny, val[1])
  315.     for i in range(len(arr2)):
  316.         arr2[i][0] -= mnx
  317.         arr2[i][1] -= mny
  318.     angle = 1
  319.     for (x,y) in arr2:
  320.         angle = min(angle, y / max(x, 1))
  321.  
  322.     for i in range(len(arr2)):
  323.         (x, y) = arr2[i]
  324.         arr2[i] = (x, y - angle * x)
  325.     arr2 = findBest(arr2, w, h)
  326.     arr2 = findBest(arr2, w, h)
  327.     for val in arr2:
  328.         mp[val[0], val[1]] = black
  329.    
  330.     arr2 = []
  331.     for x in range(w):
  332.         for y in range(h):
  333.             if mp[x, y] == black:
  334.                 arr2.append([x, y])
  335.                 mp[x, y] = white
  336.     mnx = arr2[0][0]
  337.     mny = arr2[0][1]
  338.     for val in arr2:
  339.         mnx = min(mnx, val[0])
  340.         mny = min(mny, val[1])
  341.     for i in range(len(arr2)):
  342.         arr2[i][0] -= mnx
  343.         arr2[i][1] -= mny
  344.    
  345.     for val in arr2:
  346.         mp[val[0], val[1]] = black
  347.        
  348.     for x in range(w):
  349.         for y in range(h // 2):
  350.             mp[x, y], mp[x, h - 1 - y] = mp[x, h - 1 - y], mp[x, y]
  351.     for x in range(w):
  352.         for y in range(h):
  353.             if x == 0 or y == 0 or x == w - 1 or y == h - 1:
  354.                 mp[x, y] = black
  355.     W = w
  356.     H = h
  357.     arr.append(mp)
  358.    
  359. size = len(arr)
  360.  
  361. a = int(size ** 0.5 + 0.5)
  362. b = (size + a - 1) // a
  363.  
  364. result = Image.new('RGB', (W * a, H * b), color = 'white')
  365. pixel_map = result.load()
  366.  
  367. for i in range(a):
  368.     for j in range(b):
  369.         for x in range(W):
  370.             for y in range(H):
  371.                 if i * b + j >= size:
  372.                     break
  373.                 pixel_map[i * W + x, j * H + y] = arr[i * b + j][x, y]
  374.  
  375. result.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement