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
- white = (255, 255, 255)
- black = (0, 0, 0)
- def GetPathToImage(index):
- return 'C:\\Users\\User\\Desktop\\university\\educational_and_research_work\\Filters\\for_Andrew\\ (%d).png' % index
- def GetKMeanColors(listOfPixels, k):
- def GetRandColor():
- return (rnd(256), rnd(256), rnd(256))
- def GetColorDist(a, b):
- return sum([(a[i] - b[i]) ** 2 for i in range(3)])
- arr = [GetRandColor() for i in range(k)]
- def GetClass(color):
- dist = 10 ** 10 #inf
- index = -1
- for i in range(k):
- currentDist = GetColorDist(color, arr[i])
- if currentDist < dist:
- dist = currentDist
- index = i
- return index
- n = len(listOfPixels)
- def GetTotalError():
- result = 0
- for i in range(n):
- result += GetColorDist(arr[currentClass[i]], listOfPixels[i][0]) * listOfPixels[i][1]
- return result
- currentClass = [0 for i in range(n)]
- def GetDirections():
- result = [[0, 0, 0] for i in range(k)]
- cnt = [0 for i in range(k)]
- for i in range(n):
- r, g, b = listOfPixels[i][0]
- thisCount = listOfPixels[i][1]
- thisClass = currentClass[i]
- result[thisClass][0] += r * thisCount
- result[thisClass][1] += g * thisCount
- result[thisClass][2] += b * thisCount
- cnt[thisClass] += thisCount
- for i in range(k):
- if cnt[i] != 0:
- for j in range(3):
- result[i][j] //= cnt[i]
- return result
- ITR = 50
- for itr in range(ITR):
- currentClass = [GetClass(listOfPixels[i][0]) for i in range(n)]
- dirs = GetDirections()
- for i in range(k):
- r, g, b = arr[i]
- mr, mg, mb = dirs[i]
- arr[i] = ((r + mr) // 2, (g + mg) // 2, (b + mb) // 2)
- colorToColor = {}
- for i in range(n):
- colorToColor[listOfPixels[i][0]] = arr[currentClass[i]]
- return arr, GetTotalError(), colorToColor
- def Filter(number):
- name = GetPathToImage(number)
- try:
- img = Image.open(name).convert('RGB')
- except FileNotFoundError:
- return (0, 0, 0, 0)
- pixel_map = img.load()
- w, h = img.size
- countMapOfColors = {}
- for i in range(w):
- for j in range(h):
- cur = pixel_map[i, j]
- if cur not in countMapOfColors:
- countMapOfColors[cur] = 0
- countMapOfColors[cur] += 1
- listOfPixels = []
- for color in countMapOfColors:
- listOfPixels.append((color, countMapOfColors[color]))
- k = 5
- currentColors, currentError, currentMapOfColors = GetKMeanColors(listOfPixels, k)
- for i in range(w):
- for j in range(h):
- pixel_map[i, j] = currentMapOfColors[pixel_map[i, j]]
- countMapOfColors = {}
- for i in range(w):
- for j in range(h):
- cur = pixel_map[i, j]
- if cur not in countMapOfColors:
- countMapOfColors[cur] = 0
- countMapOfColors[cur] += 1
- precents = 10 # если больше precents процентов на картинке данного цвета, то будем считать, что это фон
- totalSize = w * h
- backgroundColors = set()
- backgroundColors.add(white) # чтобы сразу убрать белые точки
- for color in countMapOfColors:
- if countMapOfColors[color] / totalSize * 100 >= precents:
- backgroundColors.add(color)
- for x in range(w):
- for y in range(h):
- if pixel_map[x, y] in backgroundColors:
- pixel_map[x, y] = white
- steps = [(dx, dy) for dy in range(-1, 2) for dx in range(-1, 2)]
- def BlurImage():
- arr = [[0 for y in range(h)] for x in range(w)]
- result = [[0 for y in range(h)] for x in range(w)]
- matrix = [
- [-1, -1, -1],
- [-1, 9, -1],
- [-1, -1, -1]]
- def Get(i, j):
- ans = [0, 0, 0]
- for (dx, dy) in steps:
- x = min(w - 1, max(i + dx, 0))
- y = min(h - 1, max(j + dy, 0))
- for ind in range(3):
- ans[ind] += pixel_map[x, y][ind] * matrix[dx + 1][dy + 1]
- return (ans[0], ans[1], ans[2])
- for x in range(w):
- for y in range(h):
- arr[x][y] = Get(x, y)
- for x in range(w):
- for y in range(h):
- pixel_map[x, y] = arr[x][y]
- first = [[pixel_map[x, y] for y in range(h)] for x in range(w)]
- BlurImage()
- second = [[pixel_map[x, y] for y in range(h)] for x in range(w)]
- print('done')
- return first, second
- arr = []
- for number in range(1, 10):
- arr.append(Filter(number))
- w = len(arr[0][0])
- h = len(arr[0][0][0])
- img = Image.new('RGB', (w * 2, h * len(arr)))
- mp = img.load()
- for i in range(len(arr)):
- for j in range(2):
- for x in range(w):
- for y in range(h):
- mp[x + j * w, i * h + y] = arr[i][j][x][y]
- img.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement