Sentinel 2 Görüntülerinin Python ile Sınıflandırılması

1
109
sentinel

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.

5 1 oy
Ortalama Puan

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()

sentinel

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()

sentinel

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()

sentinel

Herkese kolay gelsin.

Abone Ol
Bildirim Al
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Yorum
En Yeniler
Eskiler Beğenilenler
Satıriçi Geribildirimi
Tüm yorumları göster.
Ahmet Vural
Ahmet Vural
17 Haziran 2020 11:20
Puan :
     

Teşekkür ederim çok faydalı bir yazı olmuş. Kolay gelsin.