Python-Imaging ile Temel İşlemler

İçindekiler

Paket Hakkında

Python-Imaging pakedi Python ile resim dosyaları üzerinde çalışmak için gereken fonksiyonları içerir.

PyPI:http://pypi.python.org/pypi/PIL
Kurulum:pip install pil
Dökümantasyon:http://effbot.org/imagingbook/

Resimler Hakkında (1)

image = (
    width,
    height,
    [(r0, g0, b0),
     (r1, g1, b1),
     (r2, g2, b2),
     # snip
     (rn, gn, bn)]
)

Yukarıdaki veri yapısında 3 kanallı (yeşil, kırmızı, mavi) gerçek renkli bir resmi saklayabiliriz.

Resimler Hakkında (2)

image = (
    width,
    height,
    [v0,
     v1,
     v2,
     # snip
     vn]
)

Tek kanallı (siyah-beyaz) resimler için.

Suya Sabuna Dokunmayan Bir Örnek

from PIL import Image


image_instance = Image.new('RGB', (640, 480), (0, 0, 0))

# some awesome image manipulation code here

image_instance.save('filename.png')

Örnek 1: İzometrik Eğriler Çizelim

Bir yükseklik haritasını girdi olarak kullanarak üzerine eşyükselti eğrileri yerleştireceğiz.

img/result.png

Örnek 1: Gürültü Sentezi (1)

import random
from PIL import Image, ImageOps

def create_noise(width, height, scale, temporary_border=2):
    raise NotImplementedError

Örnek 1: Gürültü Sentezi (2)

def create_noise(width, height, scale, temporary_border=2):
    size = (width + 2 * temporary_border,
            height + 2 * temporary_border)
    img = Image.new('L', size)
    # super-cool noise creation happens
    img = img.resize((size[0] * scale, size[1] * scale),
                    Image.BICUBIC)
    img = ImageOps.crop(img, scale * temporary_border)
    return img

Örnek 1: Gürültü Sentezi (3)

img resmi üzerindeki her bir piksele rastgele bir değer atıyoruz.

img_cursor = img.load()
for y in range(size[1]):
    for x in range(size[0]):
        img_cursor[x, y] = random.randint(0, 255)

Örnek 1: Gürültü Sentezi (4)

def create_noise(width, height, scale, temporary_border=2):
    size = (width + 2 * temporary_border,
            height + 2 * temporary_border)
    img = Image.new('L', size)
    img_cursor = img.load()
    for y in range(size[1]):
        for x in range(size[0]):
            img_cursor[x, y] = random.randint(0, 255)
    img = img.resize((size[0] * scale, size[1] * scale),
                    Image.BICUBIC)
    img = img.filter(ImageFilter.SMOOTH)
    img = ImageOps.crop(img, scale * temporary_border)
    return img

Örnek 1: Gürültü Sentezi (5)

Bir resim ince detaylar için...

img/noise1.png
noise_1 = create_noise(128, 128, 2)

Örnek 1: Gürültü Sentezi (6)

...bir resim daha büyük detaylar için...

img/noise2.png
noise_2 = create_noise(32, 32, 8)

Örnek 1: Gürültü Sentezi (7)

...bir resim de en kaba detaylar için.

img/noise3.png
noise_3 = create_noise(8, 8, 32)

Örnek 1: Gürültü Sentezi (8)

Üçünü birleştirdiğimizde doğal bir desen elde ederiz:

img/noise_combined.png
noise_combined = ImageChops.blend(noise_1, noise_2, 0.667)
noise_combined = ImageChops.blend(noise_combined, noise_3, 0.667)
noise_combined.save('noise_combined.png')

Örnek 1: Gürültü Sentezi (9)

def naive_perlin(width, height, n, c=1):
    img = Image.new('L', (width, height), 127)
    for i in range(c, n+c):
        f = 2 ** i
        noise = create_noise(width/f, height/f, f)
        img = ImageChops.blend(img, noise, 0.333)
    img = ImageOps.autocontrast(img)
    return img

Örnek 1: Gürültü Sentezi (10)

Yükseklik haritası için kullanacağımız gürültü resmi:

img/noise.png
WIDTH = HEIGHT = 256
random.seed(369147258)
hm_img = naive_perlin(WIDTH, HEIGHT, 5, 4)

Örnek 1: İzometrik Eğriler (1)

Yükseklik haritamızdaki her pikselin değeri belli bir yüksekliğe işaret ediyor.

Aynı yükseklikteki noktaları birleştiren eğrilere eşyükselti eğrileri denir.

Örnek 1: İzometrik Eğriler (2)

def draw_isometric_curve(img, value, threshold=1.55):
    def _curve_func(p_value):
        return max(threshold - abs(p_value - value), 0) * 255
    # make sure we have float and offset a little further
    threshold += 0.05
    curve_img = Image.eval(img.copy(), _curve_func)
    curve_img = curve_img.filter(ImageFilter.SMOOTH_MORE)
    curve_img = ImageOps.autocontrast(curve_img)
    return curve_img

Örnek 1: İzometrik Eğriler (3)

img/contours_example.png
contours_example = draw_isometric_curve(noise_img, 127)

Örnek 1: İzometrik Eğriler (4)

def draw_contours(img, count=8):
    value = 256 / count
    contours = [draw_isometric_curve(hm_img, c*value) \
                for c in range(count)]
    return reduce(ImageChops.add, contours)

Örnek 1: İzometrik Eğriler (5)

img/noise.png img/contours.png
contour_img = draw_contours(hm_img)

Örnek 1: Sonuç

img/noise.png img/contours.png img/result.png
result = ImageChops.screen(ImageOps.colorize(hm_img,
                                            (16, 8, 256),
                                            (255, 64, 196)),
                           ImageOps.colorize(contour_img,
                                            (0, 0, 0),
                                            (64, 256, 96)))

Örnek 2: Soyut Resim Filtresi

img/tesla.jpeg img/tesla_squares_coarse.png img/tesla_squares_fine.png

Örnek 2: Kuşbakışı

import random
from PIL import Image, ImageFilter, ImageDraw


def square_brush(img, count, size_min=4, size_max=32):
    raise NotImplementedError


random.seed(12345)
img = Image.open('tesla.jpeg')
squares_coarse = square_brush(img, 3000, 5, 25)
squares_coarse.save('tesla_squares_coarse.png')

Örnek 2: Kare Fırça Filtresi (1)

def square_brush(img, count, size_min=4, size_max=32):
    output = Image.new('RGB', img.size, (0, 0, 0))
    img_cursor = img.filter(ImageFilter.MedianFilter(9)).load()
    draw = ImageDraw.Draw(output)
    for _ in range(count):
        searching = 10
        while searching:
            x = random.randint(0, img.size[0] - 1)
            y = random.randint(0, img.size[1] - 1)
            if output.getpixel((x, y)) == (0, 0, 0):
                searching = 0
            else:
                searching -= 1
        box_size = random.randint(size_min, size_max) / 2
        box = (x-box_size, y-box_size, x+box_size, y+box_size)
        draw.rectangle(box, fill=img_cursor[x, y])
    return output

Örnek 2: Kare Fırça Filtresi (2)

def square_brush(img, count, size_min=4, size_max=32):
    output = Image.new('RGB', img.size, (0, 0, 0))
    img_cursor = img.filter(ImageFilter.MedianFilter(9)).load()
    # classy yet sexy brush strokes
    return output

Örnek 2: Kare Fırça Filtresi (3)

draw = ImageDraw.Draw(output)
for _ in range(count):
    searching = 10
    ## start of modified code ##
    # Naive implementation
    x = random.randint(0, img.size[0] - 1)
    y = random.randint(0, img.size[1] - 1)
    ## end of modified code ##
    box_size = random.randint(size_min, size_max) / 2
    box = (x-box_size, y-box_size, x+box_size, y+box_size)
    draw.rectangle(box, fill=img_cursor[x, y])

Örnek 2: Kare Fırça Filtresi (4)

searching = 10
while searching:
    x = random.randint(0, img.size[0] - 1)
    y = random.randint(0, img.size[1] - 1)
    if output.getpixel((x, y)) == (0, 0, 0):
        searching = 0
    else:
        searching -= 1

Örnek 2: İlk Deneme

img/tesla.jpeg img/tesla_squares_coarse.png
squares_coarse = square_brush(img, 3000, 5, 25)

Örnek 2: Biraz Daha Donanım Katalım

img/tesla.jpeg img/tesla_squares_fine.png
squares_fine = square_brush(img, 9000, 3, 15)

Bitti

Teşekkür ederim.