BAB 6: NDVI: Mengukur Kehijauan Tanaman dengan Satu Rumus
#Studi kasus: "Kebun mana yang paling hijau?"
Kepala Seksi ingin membandingkan kondisi vegetasi KPH Alpha, Beta, dan Gamma. Memandangi citra warna palsu membuat Analis Muda hanya bisa berkata "yang ini lebih merah". Kepala Seksi menginginkan angka. Bab ini memperkenalkan indeks vegetasi NDVI, yang mengubah dua band menjadi satu angka kehijauan untuk tiap piksel.
#Konsep: NDVI dalam tiga kalimat
Daun sehat menyerap cahaya merah untuk berfotosintesis dan memantulkan banyak inframerah dekat, seperti cermin yang hanya memantulkan satu warna. NDVI membandingkan kedua pantulan itu dalam satu rumus: selisihnya dibagi jumlahnya. Hasilnya angka antara -1 dan 1, dan makin tinggi berarti makin lebat dan sehat vegetasinya.
Istilah baru bab ini:
- Indeks vegetasi: angka hasil rumus beberapa band untuk menonjolkan vegetasi.
- NDVI (Normalized Difference Vegetation Index): indeks vegetasi yang paling umum.
- Pantulan (reflektansi): bagian cahaya yang dipantulkan permukaan.
- Raster calculator: alat hitung antar-raster, piksel demi piksel.
- Statistik zonal: ringkasan nilai raster (misalnya rata-rata) di dalam tiap poligon.

#Rumusnya
NDVI = (NIR - Merah) / (NIR + Merah)NIR adalah band inframerah dekat (band 4, B08). Merah adalah band 3 (B04). Contoh untuk hutan sintetis: pantulan NIR 0,40 dan merah 0,03. NDVI = (0,40 - 0,03) / (0,40 + 0,03) = 0,86.
#Cara membaca nilai NDVI
| Kisaran NDVI | Biasanya berarti |
|---|---|
| Di bawah 0 | Air |
| 0 sampai sekitar 0,3 | Lahan terbuka atau tanah |
| Sekitar 0,3 sampai 0,6 | Vegetasi jarang atau tanaman muda |
| Di atas sekitar 0,6 | Vegetasi lebat |
Kisaran ini pedoman kasar, bukan hukum. Nilai batas berbeda antar-citra dan antar-daerah. [kemungkinan: kebiasaan umum; batas kelas di buku ini pilihan penulis untuk latihan]
#Angka dari data latihan
NDVI rata-rata per jenis tutupan (data sintetis; dihitung dari piksel):
| Tutupan | NDVI rata-rata |
|---|---|
| Hutan | 0,860 |
| Kebun | 0,714 |
| Sawah atau tanaman muda | 0,515 |
| Lahan terbuka | 0,128 |
| Air | -0,201 |
Seluruh citra: NDVI terkecil -0,328, terbesar 0,903, rata-rata 0,735. Dikelompokkan dengan batas 0, 0,3, dan 0,6:
| Kelas | Piksel | Luas (ha) |
|---|---|---|
| 1 Air (sampai 0) | 1.203 | 0,48 |
| 2 Lahan terbuka (0 sampai 0,3) | 1.767 | 0,71 |
| 3 Vegetasi jarang (0,3 sampai 0,6) | 4.994 | 2,00 |
| 4 Vegetasi rapat (di atas 0,6) | 32.036 | 12,81 |
NDVI rata-rata per KPH: Alpha 0,814, Beta 0,614, Gamma 0,755. Beta paling rendah karena separuhnya adalah sawah atau tanaman muda. Alpha tinggi karena hampir seluruhnya hutan. Semua angka diuji di QGIS 4.0.2 (Skrip 6.1).

#Bagian A: QGIS
#Bagian A: Menghitung NDVI di QGIS
#Langkah 1: Raster Calculator
- Pastikan
Citra_4banddari Bab 2 ada di proyek. - Buka Raster ► Raster Calculator….
- Di kotak Raster Calculator Expression, ketik rumus berikut. Nama band ditulis
nama_layer@nomor_band:
("Citra_4band@4" - "Citra_4band@3") / ("Citra_4band@4" + "Citra_4band@3")- Pada Output layer, pilih berkas, misalnya
C:\kerja_b3\NDVI.tif. Biarkan format GeoTIFF. - Pilih satu band
Citra_4banddi daftar Raster Bands, lalu klik tombol Selected Layer Extent supaya ukuran hasil sama dengan citra. Klik OK. [CEK: letak tombol] - Hasilnya layer
NDVI. Beri warna di Symbology ► Singleband pseudocolor dengan deretan merah ke kuning ke hijau, atau pilih mode Min/Max agar tampilannya jelas.
Anda mendapat nilai NDVI -0,328 sampai 0,903 (rata-rata 0,735). Bila nilainya tidak seperti itu, periksa nomor band dan tanda kurungnya.
#Langkah 2: mengelompokkan NDVI
Gunakan Reclassify by table (Bab 5) pada NDVI.tif dengan tabel:
| Minimum | Maximum | Value | Arti |
|---|---|---|---|
| -1 | 0 | 1 | Air |
| 0 | 0,3 | 2 | Lahan terbuka |
| 0,3 | 0,6 | 3 | Vegetasi jarang |
| 0,6 | 1,01 | 4 | Vegetasi rapat |
Pilih Range boundaries = min < value <= max (bawaan), Output data type = Byte. Hitung luas dengan Raster layer unique values report.
#Langkah 3: rata-rata NDVI per KPH
- Buka Zonal statistics di Processing Toolbox.
- Isi Input layer dengan
Batas_KPH, Raster layer denganNDVI, dan Raster band dengan 1. - Pada Statistics to calculate, centang Mean.
- Isi Output column prefix dengan
ndvi_, lalu klik Run. - Buka tabel atribut hasil. Kolom
ndvi_meanberisi: Alpha 0,814, Beta 0,614, Gamma 0,755.
#Dengan Python (opsional)
Berkas skrip/b3_06_ndvi.py. Jalankan Skrip 2.1 lebih dulu.
import processing
from qgis.core import QgsRasterLayer, QgsProject
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
DATA = r"D:/data/paket-b3"
OUT = r"C:/kerja_b3"
stack = QgsRasterLayer(OUT + "/Citra_4band.tif", "Citra_4band")
nir = QgsRasterCalculatorEntry()
nir.ref, nir.raster, nir.bandNumber = "nir@1", stack, 4 # band 4 = inframerah dekat
red = QgsRasterCalculatorEntry()
red.ref, red.raster, red.bandNumber = "red@1", stack, 3 # band 3 = merah
rumus = '("nir@1" - "red@1") / ("nir@1" + "red@1")'
calc = QgsRasterCalculator(rumus, OUT + "/NDVI.tif", "GTiff", stack.extent(), stack.width(), stack.height(),
[nir, red], QgsProject.instance().transformContext())
print("Kode hasil (0 = sukses):", calc.processCalculation())
st = processing.run("native:rasterlayerstatistics", {"INPUT": OUT + "/NDVI.tif", "BAND": 1})
print("NDVI min/maks/rata-rata:", round(st["MIN"], 3), "/", round(st["MAX"], 3), "/", round(st["MEAN"], 3))
# Kelompokkan: sampai 0 = air; 0-0,3 = lahan terbuka; 0,3-0,6 = vegetasi jarang; di atas 0,6 = vegetasi rapat
processing.run("native:reclassifybytable", {
"INPUT_RASTER": OUT + "/NDVI.tif", "RASTER_BAND": 1,
"TABLE": [-1, 0, 1, 0, 0.3, 2, 0.3, 0.6, 3, 0.6, 1.01, 4],
"RANGE_BOUNDARIES": 0, "NODATA_FOR_MISSING": True, "NO_DATA": 255, "DATA_TYPE": 0,
"OUTPUT": OUT + "/NDVI_kelas.tif"})
u = processing.run("native:rasterlayeruniquevaluesreport", {"INPUT": OUT + "/NDVI_kelas.tif", "BAND": 1,
"OUTPUT_TABLE": "TEMPORARY_OUTPUT"})
nama = {1: "Air", 2: "Lahan terbuka", 3: "Vegetasi jarang", 4: "Vegetasi rapat"}
for f in u["OUTPUT_TABLE"].getFeatures():
k = int(f["value"])
print(k, nama.get(k, "NoData"), f["count"], "piksel =", round(f["count"] * 4 / 10000, 2), "ha")
# Rata-rata NDVI per KPH
z = processing.run("native:zonalstatisticsfb", {
"INPUT": DATA + "/Batas_KPH.gpkg|layername=Batas_KPH", "INPUT_RASTER": OUT + "/NDVI.tif", "RASTER_BAND": 1,
"COLUMN_PREFIX": "ndvi_", "STATISTICS": [2], "OUTPUT": "TEMPORARY_OUTPUT"})
for f in z["OUTPUT"].getFeatures():
print(f["NAMA_KPH"], "NDVI rata-rata:", round(f["ndvi_mean"], 3))Keluaran yang diuji di QGIS 4.0.2:
Kode hasil (0 = sukses): 0
NDVI min/maks/rata-rata: -0.328 / 0.903 / 0.735
1 Air 1203 piksel = 0.48 ha
2 Lahan terbuka 1767 piksel = 0.71 ha
3 Vegetasi jarang 4994 piksel = 2.0 ha
4 Vegetasi rapat 32036 piksel = 12.81 ha
KPH Alpha NDVI rata-rata: 0.814
KPH Beta NDVI rata-rata: 0.614
KPH Gamma NDVI rata-rata: 0.755#Jebakan: rumus NDVI yang tampak benar tetapi salah
Alat Raster calculator dari grup GDAL (gdal:rastercalculator) memakai huruf A, B, dan seterusnya untuk layer. Ujilah rumus berikut dengan A = band NIR (Citra_B08) dan B = band merah (Citra_B04), keduanya bertipe UInt16, dan Output raster type = Float32:
| Rumus | Hasil min, maks, rata-rata |
|---|---|
(A-B)/(A+B) | 0,001 / 155,83 / 4,68 (salah) |
(A.astype(float)-B)/(A.astype(float)+B) | -0,328 / 0,903 / 0,735 (benar) |
Pada rumus pertama, piksel air dan lahan terbuka punya merah lebih besar dari NIR sehingga selisihnya negatif. Pada bilangan UInt16, selisih negatif "membungkus" menjadi angka sangat besar, lalu NDVI ikut melonjak melebihi 1. Rumus kedua mengubah NIR menjadi pecahan lebih dulu, sehingga aman. Angka diuji di QGIS 4.0.2.
#Bagian B: ArcGIS Pro
#Bagian B: ArcGIS Pro
- Gunakan Raster Calculator (Spatial Analyst Tools). Alat ini hanya untuk dipakai di aplikasi (panel Geoprocessing atau ModelBuilder), bukan skrip, menurut dokumentasi Esri.
- Ketik ekspresi dengan sintaks aljabar peta (map algebra). Karena band bilangan bulat, ubah dulu ke pecahan dengan fungsi Float:
(Float("Citra_4band.tif - Band_4") - Float("Citra_4band.tif - Band_3")) / (Float("Citra_4band.tif - Band_4") + Float("Citra_4band.tif - Band_3"))Nama layer di ekspresi mengikuti daftar Rasters pada alat. [CEK]
- Alasan memakai Float: dokumentasi alat Divide menyebut bahwa bila kedua masukan bilangan bulat, yang terjadi adalah pembagian bilangan bulat dan hasilnya bilangan bulat (3 dibagi 2 menjadi 1). Dokumentasi Raster Calculator sendiri tidak menjelaskan ini, jadi uji hasilnya. [CEK]
- Cara lain: fungsi raster NDVI. Menurut dokumentasi Esri, parameternya Visible Band ID (band merah), Infrared Band ID (band inframerah dekat), dan Scientific Output (nilai -1 sampai 1). Untuk
Citra_4band, merah adalah band 3 dan inframerah dekat band 4. Lokasi fungsi di antarmuka: tab Imagery, bagian Raster Functions. [CEK] - Statistik zonal: alat Zonal Statistics as Table dengan zona
Batas_KPHdan statistik rata-rata. [CEK]
#Bagian C: ArcMap 10.8
#Bagian C: ArcMap 10.8
- Buka Raster Calculator (toolbox Spatial Analyst, toolset Map Algebra). Alat ini memakai sintaks Python dan, menurut dokumentasi Esri, hanya untuk dipakai di dalam aplikasi atau ModelBuilder.
- Gunakan fungsi Float seperti di Pro agar pembagian menghasilkan pecahan:
(Float("Citra_4band.tif - Band_4") - Float("Citra_4band.tif - Band_3")) / (Float("Citra_4band.tif - Band_4") + Float("Citra_4band.tif - Band_3"))[CEK]
- Ekstensi Spatial Analyst diperlukan.
- Statistik zonal: Zonal Statistics as Table (Spatial Analyst, toolset Zonal). [CEK]
#Cek paham
- Mengapa vegetasi sehat bernilai NDVI tinggi?
- Berapa kisaran nilai NDVI yang mungkin?
- Mengapa rumus
(A-B)/(A+B)pada band UInt16 bisa salah di alat GDAL?
Jawaban:
- Daun sehat menyerap merah dan memantulkan banyak inframerah dekat. Selisihnya besar, jadi NDVI mendekati 1.
- Antara -1 dan 1.
- Selisih negatif pada bilangan tanpa tanda "membungkus" menjadi angka besar, sehingga hasil melebihi 1. Ubah ke pecahan dulu (
astype(float)).
#Kesalahan umum
- Salah memilih band. Tertukarnya band merah dan inframerah dekat membalik tanda NDVI. Cocokkan dengan Bab 2: merah band 3, NIR band 4.
- Tipe bilangan bulat. Lihat jebakan di atas. Selalu periksa min dan maks hasil.
- Menafsirkan angka mutlak sebagai kebenaran lapangan. Nilai NDVI bergantung pada sensor dan musim. Gunakan untuk membandingkan dalam satu citra, atau antar-tanggal dengan syarat yang sama.
- Menghitung rata-rata dari raster yang tidak dipotong. Rata-rata seluruh citra bukan rata-rata satu KPH. Pakai statistik zonal atau potong dulu (Bab 4).
#Ringkasan dan latihan
Ringkasan: NDVI = (NIR - Merah) / (NIR + Merah), berkisar -1 sampai 1. Hitung dengan Raster Calculator, kelompokkan dengan reklasifikasi, dan ringkas per KPH dengan statistik zonal. Waspadai tipe bilangan bulat.
Latihan:
- Hitung NDVI, lalu temukan nilainya di titik bukaan lahan Alpha (E 312145, N 9996065). Jawaban uji: sekitar 0,15 (nilai asli di piksel itu 0,149; rata-rata lahan terbuka 0,128).
- Hitung NDVI rata-rata per KPH dan urutkan dari yang tertinggi. Jawaban uji: Alpha 0,814, Gamma 0,755, Beta 0,614.
- Mengapa Gamma lebih rendah dari Alpha padahal sama-sama hutan? Jawaban: Gamma memuat sungai (NDVI negatif) dan bukaan lahan bulat yang menurunkan rata-rata.
#Tabel perbandingan: NDVI
| Hal | QGIS | ArcGIS Pro | ArcMap 10.8 |
|---|---|---|---|
| Alat hitung | Raster ► Raster Calculator | Raster Calculator (Spatial Analyst) | Raster Calculator (Spatial Analyst) |
| Penulisan band | "layer@4" | Nama dari daftar Rasters | Nama dari daftar Rasters |
| Cegah pembagian bulat | Raster Calculator QGIS aman (diuji); alat GDAL perlu astype(float) | Pakai Float [CEK] | Pakai Float [CEK] |
| Fungsi NDVI siap pakai | Tidak ada alat bawaan di buku ini | Fungsi raster NDVI [CEK] | Perlu dicek [CEK] |
| Statistik per poligon | Zonal statistics | Zonal Statistics as Table [CEK] | Zonal Statistics as Table [CEK] |