88 lines
2.2 KiB
Python
88 lines
2.2 KiB
Python
import logging
|
|
|
|
from PIL import Image, ImageFilter
|
|
import scipy.signal
|
|
import numpy as np
|
|
|
|
logging.getLogger(__name__)
|
|
|
|
sobel_x_kernel = np.array((
|
|
(1, 0, -1),
|
|
(2, 0, -2),
|
|
(1, 0, -1)
|
|
))
|
|
|
|
sobel_y_kernel = np.transpose(sobel_x_kernel)
|
|
|
|
def difference_of_gaussians(img: Image.Image, blur_strength_1: float | None = 1.0, blur_strength_2: float | None = 1.2) -> Image.Image:
|
|
blur_1 = img.filter(ImageFilter.GaussianBlur(blur_strength_1))
|
|
blur_2 = img.filter(ImageFilter.GaussianBlur(blur_strength_2))
|
|
|
|
w, h = img.size
|
|
|
|
dog = Image.new(img.mode, img.size)
|
|
|
|
for pixel_y in range(h):
|
|
for pixel_x in range(w):
|
|
|
|
coords = (pixel_x, pixel_y)
|
|
|
|
p1 = blur_1.getpixel(coords)
|
|
p2 = blur_2.getpixel(coords)
|
|
|
|
p1 = np.array(p1)
|
|
p2 = np.array(p2)
|
|
new_pixel = p2 - p1
|
|
|
|
dog.putpixel(coords, tuple(new_pixel.tolist()))
|
|
|
|
return dog
|
|
|
|
def sobel(img: Image.Image, gradient_threshold: int | None = 20) -> tuple[Image.Image, np.ndarray]:
|
|
logging.debug(img.size)
|
|
|
|
img = img.convert('L')
|
|
img.save('debug/test-L.png')
|
|
|
|
logging.debug('Sobel Operator')
|
|
|
|
logging.debug(img.size)
|
|
|
|
pixels = np.array(img)
|
|
logging.debug(f'pixels size: {pixels.size}')
|
|
|
|
dx = scipy.signal.correlate(pixels, sobel_x_kernel, mode='same')
|
|
dy = scipy.signal.correlate(pixels, sobel_y_kernel, mode='same')
|
|
logging.debug(f'dx size: {dx.size}')
|
|
|
|
edges = np.sqrt(np.square(dx) + np.square(dy))
|
|
edges[edges>255] = 255
|
|
|
|
logging.debug(f'edges size: {edges.size}')
|
|
|
|
gradient = np.arctan2(dy.flatten(), dx.flatten())
|
|
gradient = np.absolute(gradient)
|
|
print(gradient)
|
|
print(np.average(gradient))
|
|
gradient[gradient > gradient_threshold] = 0
|
|
|
|
pil_edges = edges.astype(np.uint8)
|
|
newimg = Image.fromarray(pil_edges, mode='L')
|
|
logging.debug(f'New Img Size: {newimg.size}')
|
|
|
|
return (newimg, gradient)
|
|
|
|
def average_colors(colors: list) -> tuple:
|
|
colors = np.array(colors)
|
|
|
|
np.average(colors)
|
|
|
|
sum = np.zeros(len(colors[0]))
|
|
for c in colors:
|
|
sum += c
|
|
|
|
sum /= len(colors)
|
|
|
|
return tuple(sum.astype(np.uint8).tolist())
|
|
|