Repository: microsoft/torchgeo

Issue:
Is NDVI calculation correct?
### Description

Hi,
I had negative NDVI values therefore I  was checking the code for  indices calculation and found a small issue:

According to https://github.com/microsoft/torchgeo/blob/main/torchgeo/transforms/indices.py 
you calculate the NDVI by using the following formula:

\text{NDVI} = \frac{\text{R} - \text{NIR}}{\text{R} + \text{NIR}}

which is the negative of NDVI, right? The common NDVI formula is: ( NIR -RED )/  (Red+NIR)

Is it a bug or did I miss anything?

### Steps to reproduce

I just did code analysis.

### Version

commit 35fb022 on Jul 11


Discussion:
Good catch! You're right, our NDVI calculation is definitely wrong. The only reason we didn't notice this in our tutorials is that we're reversing the colormap to get the results we expect. I'll fix this ASAP and it will be included in the next bugfix release.

P.S. NDVI can be negative, this is often the case over water bodies. But you're probably seeing the reverse where NDVI is only positive over water bodies, which is definitely incorrect.

Resolving patch:
diff --git a/torchgeo/transforms/indices.py b/torchgeo/transforms/indices.py
--- a/torchgeo/transforms/indices.py
+++ b/torchgeo/transforms/indices.py
@@ -160,21 +160,21 @@ class AppendNDVI(AppendNormalizedDifferenceIndex):
 
     .. math::
 
-       \text{NDVI} = \frac{\text{R} - \text{NIR}}{\text{R} + \text{NIR}}
+       \text{NDVI} = \frac{\text{NIR} - \text{R}}{\text{NIR} + \text{R}}
 
     If you use this index in your research, please cite the following paper:
 
     * https://doi.org/10.1016/0034-4257(79)90013-0
     """
 
-    def __init__(self, index_red: int, index_nir: int) -> None:
+    def __init__(self, index_nir: int, index_red: int) -> None:
         """Initialize a new transform instance.
 
         Args:
-            index_red: index of the Red band in the image
             index_nir: index of the Near Infrared (NIR) band in the image
+            index_red: index of the Red band in the image
         """
-        super().__init__(index_a=index_red, index_b=index_nir)
+        super().__init__(index_a=index_nir, index_b=index_red)
 
 
 class AppendNDWI(AppendNormalizedDifferenceIndex):
@@ -208,7 +208,7 @@ class AppendSWI(AppendNormalizedDifferenceIndex):
 
     .. math::
 
-       \text{SWI} = \frac{\text{R} - \text{SWIR}}{\text{R} + \text{SWIR}}
+       \text{SWI} = \frac{\text{VRE1} - \text{SWIR2}}{\text{VRE1} + \text{SWIR2}}
 
     If you use this index in your research, please cite the following paper:
 
@@ -217,14 +217,14 @@ class AppendSWI(AppendNormalizedDifferenceIndex):
     .. versionadded:: 0.3
     """
 
-    def __init__(self, index_red: int, index_swir: int) -> None:
+    def __init__(self, index_vre1: int, index_swir2: int) -> None:
         """Initialize a new transform instance.
 
         Args:
-            index_red: index of the VRE1 band, e.g. B5 in Sentinel 2 imagery
-            index_swir: index of the SWIR2 band, e.g. B11 in Sentinel 2 imagery
+            index_vre1: index of the VRE1 band, e.g. B5 in Sentinel 2 imagery
+            index_swir2: index of the SWIR2 band, e.g. B11 in Sentinel 2 imagery
         """
-        super().__init__(index_a=index_red, index_b=index_swir)
+        super().__init__(index_a=index_vre1, index_b=index_swir2)
 
 
 class AppendGNDVI(AppendNormalizedDifferenceIndex):


Test patch: