Python’da sentinel görüntülerinin scikit-learn ve rasterio kullanarak kontrolsüz sınıflandırmanın nasıl gerçekleştirileceği hakkında adım adım neler yapılacağını anlatan bir yazı.
Sınıflandırma veya kontrolsüz sınıflandırma, bir görüntünün piksel değerlerini istatistiksel benzerliğe dayalı olarak belirli sayıda doğal sınıfa bölme (gruplama) veya toplama işlemidir. Bu derste, jinster-2 görüntü düzeltmeleri için rasterio ve jupyter notepad’de bulunan sınıflandırma için güçlü bir paket olan scikit-learn python paketini kullanacağız.
Scikit-learn, çeşitli sınıflandırma, regresyon ve sınıflandırma algoritmalarını içeren Python programlama dili için ücretsiz bir yazılım kütüphanesidir.
İndirmek için şu komutu kullanabilirsiniz.
conda install -c anaconda scikit-learn
Rasterio, GEOTIFF ve JP2 gibi farklı formatlarda uydu görüntüleri (bu yazıda sentinel kullanılacak) ve arazi modelleri gibi raster veri kümelerini okuyan ve yazan açık kaynaklı bir python kütüphanesidir.
İndirmek için şu komutu kullanabilirsiniz.
conda install -c conda-forge rasterio
Okuyucular aşağıdaki puanı vermişler.
Bu yazıya, yorum yaparak sen de puan verebilirsin.
Algoritma: Scikit-learn’un sınıflandırma için farklı algoritmaları vardır, bu algoritmalar doğrudan bu kütüphaneden içe aktarılabilir. K-Means kolay olmasından dolayı sınıflandırmada en çok kullanılan algoritmalardan biridir. Temel olarak n gözlemi (bizim durumumuzdaki pikseller), her bir gözlemi en yakın ortalamaya sahip kümeye ait olduğunu tespit edip k kümelerine (kullanıcı tarafından önceden tanımlanmış sınıf sayısı) bölüştürür. Bu yazı K-araçlarına dayalı olacak, ancak geri kalanını denemek için kolayca geçiş yapabilirsiniz, kod neredeyse aynı kalacak ancak sadece algoritmayı değiştirmeniz gerekecek.
Bu eğitimde Wathela Hamed sırasıyla eğitim için El-hasaheesa ve Gezira eyaletindeki / Sudan’daki Elmanagel bölgelerinin Sentinel-2 görüntüsünü kullanmış. Bende o çalışmadan sizlere aktarıyorum. Eğitimin tam koduna GITHUB üzerinden ulaşabilirsiniz.
İhtiyacınız olan tüm paketleri içe aktarmak için aşağıdaki kodu kullanıyoruz.
import rasterio as rio from rasterio.plot import show from sklearn import cluster import matplotlib.pyplot as plt import numpy as np
Ardından sentinel 2 görüntüyü açmak ve meta verilerini okumak için rasterio kullanıyoruz.
# Open the image elhas_raster = rio.open("Elhasaheesa.tif") print(elhas_raster.meta)
Meta veriler bize veri türü, boyut (genişlik, yükseklik), sayımlar (bant sayısı) ve koordinat referans sistemi gibi görüntü hakkında bilgi verir. Bu görüntüyü güzelce görselleştirmek için önce kontrastını germek-uzatmak gerekecektir, buradan görüntü geliştirme hakkında daha fazla bilgi edinebilirsiniz.
# Read, enhance and show the image elhas_arr = elhas_raster.read() # read the opened image vmin, vmax = np.nanpercentile(elhas_arr, (5,95)) # 5-95% contrast stretch # show the enhanced image plt.figure(figsize=[20,20]) show(elhas_raster, cmap='gray', vmin=vmin, vmax=vmax) plt.show()
Bu görüntünün durumuna bakacak olursak, sıralaması bantlar, yükseklik, genişlik şeklinde olduğunu göreceğiz.Bu sıralamanın yükseklik, genişlik, bantlar olarak değiştirilmesi gerekir. Bu işlem şu şekilde yapılmaktadır:
- Meta veriden yararlanarak resim boyutumuzu, değerlerimizi ve veri türümüzü kullanarak boş bir dizi oluşturma.
- Her bandı bölmek ve boş dizimizde yeniden biçimlendirmek için bir for döngüsü kullanma.
Bu döngünün sonunda, gerekli şekil sırasına sahip ve aynı boyut ve bant sayısına sahip yeni bir dizi elde edeceğiz.
# create an empty array with same dimension and data type imgxyb = np.empty((elhas_raster.height, elhas_raster.width, elhas_raster.count), elhas_raster.meta['dtype']) # loop through the raster's bands to fill the empty array for band in range(imgxyb.shape[2]): imgxyb[:,:,band] = elhas_raster.read(band+1)
Şuan neredeyse sınıflandırıcıyı eğitmeye hazırız. Fakat daha öncesinde X(genişlik) ve Y(yükseklik) ve bantları içeren boyutlarımızı tek bir boyuta düşürmemiz gerekmekte. K-means classifier kullanabilmemiz için 3 boyuttan 2 boyutlu bir ortama düşmemiz gerekiyor.
# convert to 1d array img1d=imgxyb[:,:,:3].reshape((imgxyb.shape[0]*imgxyb.shape[1],imgxyb.shape[2]))
Eğitim: Belirlenecek en önemli parametre, piksellerimizi gruplandırmak istediğimiz kümelerin sayısını temsil eden n_kümelerdir, bizim sentinel görüntümüzde üç ana sınıfı (yerleşim alanları, çıplak alanlar ve ekili alanlar) görsel olarak görebiliriz, ancak piksellerinin 4. bir grubu oluşturacağı görülebilen bölgeler dışındaki görünmeyen kısım yani siyah taraf olan bir ek sınıfımız var. K-means, maksimum sayı, yineleme sayısı ve başlatma sayısı gibi bazı parametrelere sahiptir, ancak bu yazıda bunları varsayılan olarak bırakacağız.
cl = cluster.KMeans(n_clusters=4) # create an object of the classifier param = cl.fit(img1d) # train it img_cl = cl.labels_ # get the labels of the classes img_cl = img_cl.reshape(imgxyb[:,:,0].shape) # reshape labels to a 3d array (one band only)
Ortaya çıkan görüntüyü göstermek için, her sınıfın rengini kontrol edebileceğim özel bir renk haritası kullanmak istiyorum. Dışarıdaki bölgeyi siyah olarak tutacağız ve sınıfların geri kalanı için kırmızı, yeşil ve sarı kullanacağız.
# Create a custom color map to represent our different 4 classes cmap = mc.LinearSegmentedColormap.from_list("", ["black","red","green","yellow"]) # Show the resulting array and save it as jpg image plt.figure(figsize=[20,20]) plt.imshow(img_cl, cmap=cmap) plt.axis('off') plt.savefig("elhas_clustered.jpg", bbox_inches='tight') plt.show()
Tahmin Etme: Sınıflandırıcı eğitildikten sonra, içerisindeki sınıfları göremediğimiz herhangi bir görüntüde aynı öğrenilen kümeleri tahmin etmek için kullanılabilir. Üzerinde aynı 4 sınıfı bulmak için Elmanagel mevkisini (Elhasaheesa’nın bitişiğindeki) bir sentinel görüntüsünü kullanacağız.Elmanagel’in görüntüsünü tahmin amacıyla kullanmak için yani sınıflandırıcıya gönderebilmemiz için önceki görüntüye yaptığımız tüm işlemlerin (şekli yeniden düzenleme ve 2d diziye dönüştürme) yapılması gerekir. Ayrıca, sonuçta öngörülen kümeleri göstermek için son adım da uygulanarak renklendirme yapılmalıdır.
# open the raster image elmanagel = rio.open(‘elmanagel.tif’) # create an empty array with same dimensions and data type elman_xyb = np.empty((elmanagel.height, elmanagel.width,elmanagel.count), elmanagel.meta['dtype']) # loop through the raster bands and fill the empty array in x-y-bands order for band in range(elman_xyb.shape[2]): elman_xyb[:,:,band] = elmanagel.read(band+1) # convert to 1d array elman_1d = elman_xyb[:,:,:3].reshape(elman_xyb.shape[0]*elman_xyb.shape[1], elman_xyb.shape[2]) # predict the clusters in the image pred = cl.predict(elman_1d) # reshape the 1d array predictions to x-y-bands shape order (only one band) elman_cul = pred elman_cul = elman_cul.reshape(elman_xyb[:,:,0].shape)
Şimdi orijinali ve ortaya çıkan sınıflandırılmış görüntüyü aşağıda gösterelim, ancak önce kontrast germe-uzatma yoluyla daha iyi görüntüleme için orijinal görüntüyü geliştireceğiz.
elman_arr = elmanagel.read() # Read the image vmin, vmax = np.nanpercentile(elman_arr, (5,95)) # 5–95% contrast stretch # show the original and predicted image fig, (ax1,ax2) = plt.subplots(figsize=[15,15], nrows=1,ncols=2, sharey=False,) show(elmanagel, cmap='gray', vmin=vmin, vmax=vmax, ax=ax1) show(elman_cul, cmap=cmap, ax=ax2) ax1.set_axis_off() ax2.set_axis_off() fig.savefig("pred.png", bbox_inches='tight') plt.show()
Herkese kolay gelsin.
Merhaba,
Algoritma da kullanılan .tiff uzantılı dosyayı benimle paylaşır mısınız?
Maalesef data bulunmamakta. https://bcankara.com/ucretsiz-uydu-goruntusu-indir-2/ konuyu inceleyiniz…
Teşekkür ederim çok faydalı bir yazı olmuş. Kolay gelsin.