İmaj / Görüntü İşleme Teknikleri
Standart bazı sayısal görüntü işleme tekniklerini listeleyeceğiz, referans amaçlı, mümkün olduğu kadar yaygın bilinen kütüphaneleri kullanarak kod örnekleri verilecek.
Küçültmek, Büyütmek
Ünlü kameracı görüntüsü üzerinde küçültme yapalım,
from PIL import Image
img = Image.open('img3.jpg')
new_img = img.resize((100,100), Image.BICUBIC)
new_img.save("img3_2.jpg", "JPEG")
Boyut değişimi yapılırken ANTIALIAS
, BICUBIC
, BILINEAR
ve
CUBIC
seçenekleri kullanılabilir. Küçültme, büyültme farketmez, aynı
seçenekler var, ölçü değişimi olduğunda muhakkak aradeğerleme
(interpolation) yapılması lazım, bahsedilen seçenekler bu
aradeğerlemenin nasıl yapılacağını kontrol ediyor. Aradeğerleme lazım
çünkü mesela büyütme durumunda 100x100 boyutunda bir resim 300x300
olacaksa bu 40,000 tane yeni piksel yaratılması demektir, bu
piksellere bir değer atanmalı, bu değerler mevcut değerler
kullanılarak bulunabilir, bilinen yakın olan piksellerin ortalama
değeri mesela, lineer ağırlıklı, ya da başka türlü. Üstteki seçenekler
hangi aradeğerlemenin seçileceğini kontrol ediyor.
Biraz önce küçültülen resmi şimdi geri büyültelim,
new_img3 = new_img.resize((340,340), Image.BICUBIC)
new_img3.save("img3_3.jpg", "JPEG")
Biraz kalite kaybı oldu muhakkak bu küçültme yaparken yaşanan veri kaybı yüzünden.
Bölge Kesip Çıkartmak (Crop)
x=100,y=100 ile x=200,y=200 noktalarının oluşturduğu kareyi çekip çıkartmak istersem,
new_img4 = img.crop((100, 100, 200, 200))
new_img4.save("img3_4.jpg", "JPEG")
Pürüzsüzleştirme (Smoothing)
Pürüzsüzleştirme, ya da bulanıklaştırma işlemi yapmak için bir scipy
bazlı bir de pür numpy
bazlı bir teknik göreceğiz.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd, imageio
import scipy.ndimage as ndimage
img = imageio.imread('../../../func_analysis/func_70_tvd/lenad0.jpg')
print (img.shape)
(225, 225)
img2 = ndimage.gaussian_filter(img, sigma=1)
print (img2.shape)
imageio.imwrite('img2.jpg',img2)
(225, 225)
def initialize_kernel(size , sigma):
w, h = size
x = np.linspace(-1,1,w)
y = np.linspace(-1,1, h)
x_cor, y_cor = np.meshgrid(x, y)
kernel = 1/(2*np.pi*np.power(sigma,2) )*\
np.exp((- (x_cor ** 2 + y_cor ** 2) )/
(2*np.power(sigma,2)))
kernel = kernel/np.sum(kernel) # normalization
return kernel
def conv2d(image, ftr):
s = ftr.shape + tuple(np.subtract(image.shape, ftr.shape) + 1)
sub_image = np.lib.stride_tricks.as_strided(image, shape = s,
strides = image.strides * 2)
return np.einsum('ij,ijkl->kl', ftr, sub_image)
img1 = conv2d(img,initialize_kernel((3,3),1))
print (img1.shape)
imageio.imwrite('img1.jpg',img1)
(223, 223)
Çizgiler
Bir imajdaki ana çizgileri bulmak artık görüntü işlem biliminde demirbaş haline gelmiş Canny kenar bulucusu ve Hough transformu ile yapılabilir.
from PIL import Image, ImageDraw
from skimage.transform import probabilistic_hough_line
from skimage.feature import canny
from skimage import data
im1 = Image.open('in1.jpg').convert('L')
edges1 = canny(np.array(im1), 2, 1, 25)
lines1 = probabilistic_hough_line(edges1, threshold=10, line_length=30,line_gap=3)
im1 = Image.open('in1.jpg')
for line in lines1:
p0, p1 = line
plt.plot((p0[0], p1[0]), (p0[1], p1[1]))
plt.imshow(im1)
plt.savefig('img4.jpg',quality=40)
Kayan Pencere İçinde İşlem (Sliding Window)
Bir görüntü, ya da genel olarak bir matris üzerinde bazen ufak bölgelerde işlem yapmak isteyebiliriz, mesela görüntünün her 16 x 16 piksel büyüklüğündeki bölgesine bakıp orada bir yüz aramak gerekebilir, ya da 5 x 5 alt grupların ortalama değeri lazımdır, bir tür pürüzsüzleştirme işlemi için. Kaydırılan pencere bizim tanımladığımız ölçüdeki bir pencereyi tüm imaj üzerinde kaydırarak o anda baktığı matris değerlerini alıp onlara bir işlem uygulayabilir. Bir bölge bitince kaç piksel yana, alta kayılacağı programcı tarafından tanımlanabilir, 3 x 3 pencere iki piksel yana kaydırılır mesela.
Potansiyel pürüzler görüntü üç noktalarında ne olacağı, 3 x 3 pencere kısmen
dışarı taştığında kısmı değerler döndürebilir sadece, bu noktalara ne yapılacağı
programcıya kalmış, taşan bölgelerde nan
koyulabilir, ya da pencere içindeki
değerler tekrarlanabilir.
def sliding_window(image, stepSize, windowSize):
for y in range(0, image.shape[0], stepSize):
for x in range(0, image.shape[1], stepSize):
yield image[y:y + windowSize[1], x:x + windowSize[0]]
arr = np.array([[1,2,3,4],
[2,3,4,5],
[3,4,5,6],
[4,5,6,7]])
for i,x in enumerate(sliding_window(arr,1,(2,2))):
print ('----------------------------')
print (x)
if i==5: break
----------------------------
[[1 2]
[2 3]]
----------------------------
[[2 3]
[3 4]]
----------------------------
[[3 4]
[4 5]]
----------------------------
[[4]
[5]]
----------------------------
[[2 3]
[3 4]]
----------------------------
[[3 4]
[4 5]]
Üstte taşma olan yerler eksik donduruldu, tekrarlama için
yield np.resize(image[y:y + windowSize[1], x:x + windowSize[0]],windowSize)
kodu kullanılabilir.
Kaynaklar
[1] Haidar, https://medium.com/@haidarlina4/tutorial-convert-an-image-into-a-sketch-step-by-step-e00e2f312521
Yukarı