Comparing LLMs for Programming in Remote Sensing
This is going to be a long post. So, I put the main results first and you can study the details below. This post is very close to the email length limit ;)
Executive Summary
For a test of their coding abilities, I gave the same tasks to different LLMs: reading a Sentinel-1 SLC image and displaying it using Python. The difficulty here is for the LLM to understand that Sentinel-1 SAR images in SLC format are complex images that need correct handling before they can be displayed.
Only Claude-3 Opus handled this without any problems or errors. Most others got to the correct results after the LLM received error messages and/or error descriptions and produced an improved version of the code.
The different LLMs give different additional explanations and code examples, which can be very useful.
For this time the winners are:
Claude-3 Opus
Baidu Wen Xin (4.0)
ChatGPT 4.0
Deepseek
Kimi.AI
Google Gemini Pro
However, keep in mind that the results can be different each time. For example, in a previous test, ChatGPT 4.0 provided the correct code on the first try, while this time, it needed three tries to get to the working code. So, this ranking is not final and just a quick look into the possibilities.
Quick Pro & Con
Claude-3 Opus
Solver it in one try. Good code with great explanations and best looking result..
Baidu Wen Xin (4.0)
Had an error in the first code, but solved it beautifully in the end and offered nice descriptions
ChatGPT 4.0
Good descriptions of the code and clear understanding of errors and problems, fixing all of them logically. However, needed three tries to get to the final code.
Deepseek
I got an error in the beginning and got it right on the second try, but the normalization wasn’t solved even on the third try - although Deepseek identified the problem correctly and gave helpful advice in the descriptions. Also, it provided visualization of the phase.
Kimi AI
The results were wrong in displaying the real part of the complex number rather than the absolute. However, the suggestion of the Sarpy library was actually a good one, and explanations were given.
Google Gemini Pro
No explanations were given, and the final result does not look good.
The full experiment
ChatGPT 4.0 Turbo
> Please give me a code example for reading and displaying a Sentinel-1 SLC image in PythonTo read and display a Sentinel-1 Single Look Complex (SLC) image in Python, you can use the `rasterio` library, which provides a simple API for reading and writing geospatial raster data. Sentinel-1 SLC images are stored in the SAFE format, and the actual image data is stored in TIFF files inside the SAFE folder structure. Here's a basic example of how to load and display the VH polarization channel of a Sentinel-1 SLC image using `rasterio` and `matplotlib` libraries.
First, ensure you have the necessary Python packages installed. You can install them using pip:
```bash
pip install rasterio matplotlib
```
Here's the Python code example:
```python
import rasterio
from matplotlib import pyplot as plt
# Replace this with the path to your Sentinel-1 SLC image VH polarization TIFF file
# Usually found in the "measurement" folder of the unzipped SAFE structure
slc_vh_image_path = "path/to/S1A_IW_SLC__1SDV_YYYYMMDDTHHMMSS_YYYYMMDDTHHMMSS_VV_VH.SAFE/measurement/s1a-iw1-slc-vh-YYYYMMDDTHHMMSS-YYYYMMDDTHHMMSS-001.tiff"
# Open the Sentinel-1 SLC VH polarization image
with rasterio.open(slc_vh_image_path) as src:
# Read the entire array
image_data = src.read(1)
# Display the image
plt.imshow(image_data, cmap='gray')
plt.title('Sentinel-1 SLC VH Polarization')
plt.xlabel('Range')
plt.ylabel('Azimuth')
plt.colorbar()
plt.show()
```This provided an error, as ChatGPT did not realize that SLC is delivered in complex numbers. So, I continued asking ChatGPT:
Actually, the code you provided provided the following error: ```TypeError: Image data of dtype complex64 cannot be converted to float```My apologies for the oversight. Sentinel-1 Single Look Complex (SLC) images are stored in a complex data format to preserve both amplitude and phase information. The Python libraries used for visualization, such as `matplotlib`, typically expect real-valued data. Therefore, when dealing with complex data, such as Sentinel-1 SLC images, you'll need to convert the complex data into a real-valued representation that can be visualized. A common approach is to visualize the amplitude or intensity of the signal, which can be obtained by taking the absolute value of the complex data.
Here's an updated Python code example that corrects this issue by converting the complex data into amplitude format before visualization:
```python
import rasterio
from matplotlib import pyplot as plt
import numpy as np
# Replace this with the path to your Sentinel-1 SLC image VH polarization TIFF file
slc_vh_image_path = "path/to/your/S1_SLC_image_VH_polarization.tiff"
# Open the Sentinel-1 SLC VH polarization image
with rasterio.open(slc_vh_image_path) as src:
# Read the entire array as complex numbers
complex_image_data = src.read(1)
# Convert the complex data to amplitude data for visualization
# Amplitude is calculated as the absolute value of the complex data
amplitude_image_data = np.abs(complex_image_data)
# Display the image
plt.imshow(amplitude_image_data, cmap='gray')
plt.title('Sentinel-1 SLC VH Polarization - Amplitude')
plt.xlabel('Range')
plt.ylabel('Azimuth')
plt.colorbar(label='Amplitude')
plt.show()
```
In this corrected example, `numpy` is used to calculate the absolute value of the complex data, which effectively converts the complex data to amplitude data. This amplitude data is then visualized using `matplotlib`, which should work without errors since it is real-valued.
Remember to replace `"path/to/your/S1_SLC_image_VH_polarization.tiff"` with the actual path to your Sentinel-1 SLC VH polarization TIFF file.
This example focuses on visualizing the amplitude of the signal, which is a common approach when working with radar imagery. However, depending on your analysis goals, you might be interested in other properties of the signal such as phase information, in which case you would need to adjust the visualization approach accordingly.
Please note the following points:
- You need to replace `"path/to/S1A_IW_SLC__1SDV_YYYYMMDDTHHMMSS_YYYYMMDDTHHMMSS_VV_VH.SAFE/measurement/s1a-iw1-slc-vh-YYYYMMDDTHHMMSS-YYYYMMDDTHHMMSS-001.tiff"` with the actual path to your Sentinel-1 SLC VH polarization TIFF file. Sentinel-1 SLC data is often distributed in .SAFE format, a folder structure containing metadata XML files and image data in geocoded TIFF format. The VH polarization channel is one of the two available polarizations (the other being VV), which might be of interest depending on your use case.
- The `read(1)` method reads the first band of the image. For Sentinel-1 SLC images, this typically corresponds to the amplitude information of the specified polarization.
- Sentinel-1 SLC images are large, and displaying them in full resolution might not be feasible on all systems. You might want to consider reading and displaying a subset of the image or downsampling the image for visualization purposes.
This code example focuses on loading and visualizing the image data using basic plotting. Depending on your specific needs, you might want to process the image data further (e.g., applying calibration, speckle filtering, or terrain correction algorithms) before visualization or analysis.> OK, this works. But, the displayed image is all black.hen you encounter an all-black image upon visualization, especially with SAR (Synthetic Aperture Radar) data like Sentinel-1 SLC images, it's often due to the high dynamic range of the radar amplitude data. Radar images can contain a few very bright pixels (e.g., from strong reflectors like buildings or metal structures) alongside many dark pixels (from low-reflectivity areas like water or vegetation). When plotted directly, the contrast is so high that most of the image appears black due to the majority of pixels having low amplitude values in comparison to the few very bright ones.
A common approach to address this issue is to apply a logarithmic transformation to the data before visualization, which can help to compress the dynamic range and make the underlying structures more visible. Here's how you can modify the code to include a logarithmic transformation:
```python
import rasterio
from matplotlib import pyplot as plt
import numpy as np
# Replace this with the path to your Sentinel-1 SLC image VH polarization TIFF file
slc_vh_image_path = "path/to/your/S1_SLC_image_VH_polarization.tiff"
# Open the Sentinel-1 SLC VH polarization image
with rasterio.open(slc_vh_image_path) as src:
# Read the entire array as complex numbers
complex_image_data = src.read(1)
# Convert the complex data to amplitude data
amplitude_image_data = np.abs(complex_image_data)
# Apply a logarithmic transform to the amplitude data
# Adding a small constant to avoid log(0)
log_image_data = 20 * np.log10(amplitude_image_data + 1e-6)
# Display the image
plt.imshow(log_image_data, cmap='gray')
plt.title('Sentinel-1 SLC VH Polarization - Log-Amplitude')
plt.xlabel('Range')
plt.ylabel('Azimuth')
plt.colorbar(label='Log-Amplitude (dB)')
plt.show()
```
By applying the logarithmic transformation (`20 * np.log10(amplitude_image_data + 1e-6)`), you convert the amplitude data to a decibel (dB) scale, which effectively reduces the dynamic range of the data. The `+1e-6` ensures that you don't take the logarithm of zero, which would be undefined.
After applying this transformation, you should see a more informative visualization of the Sentinel-1 SLC image, with structures and features becoming more visible. Keep in mind that the choice of visualization techniques and parameters can depend heavily on the specific characteristics of the dataset and the objectives of your analysis.
Claude-3 Opus
Please give me a code example for reading and displaying a Sentinel-1 SLC image in PythonHere's a Python code example that demonstrates how to read and display a Sentinel-1 SLC (Single Look Complex) image using the `rasterio` library:
```python
import rasterio
import numpy as np
import matplotlib.pyplot as plt
# Open the Sentinel-1 SLC image using rasterio
with rasterio.open('path/to/sentinel1_slc.tiff') as src:
# Read the image data and metadata
slc_data = src.read(1) # Read the first band (assuming single polarization)
metadata = src.meta
# Convert the complex data to magnitude (amplitude)
magnitude = np.abs(slc_data)
# Apply a logarithmic scaling to improve visualization
log_magnitude = np.log10(magnitude)
# Display the image using matplotlib
plt.figure(figsize=(10, 8))
plt.imshow(log_magnitude, cmap='gray')
plt.colorbar(label='Logarithmic Magnitude')
plt.title('Sentinel-1 SLC Image')
plt.xlabel('Range')
plt.ylabel('Azimuth')
plt.show()
```
Explanation:
1. We start by importing the necessary libraries: `rasterio` for reading the Sentinel-1 SLC image, `numpy` for numerical operations, and `matplotlib` for visualization.
2. We open the Sentinel-1 SLC image using `rasterio.open()` and provide the path to the image file. The `with` statement ensures that the file is properly closed after reading.
3. We read the image data using `src.read(1)`, assuming we want to read the first band (in case of a single polarization image). The image data is stored in the `slc_data` variable.
4. We also retrieve the metadata of the image using `src.meta`, which contains information such as spatial reference, data type, etc.
5. Since SLC data is complex-valued, we convert it to magnitude (amplitude) using `np.abs()` to obtain the absolute values of the complex numbers.
6. To improve visualization, we apply a logarithmic scaling to the magnitude values using `np.log10()`. This step is optional but can help enhance the visual contrast of the image.
7. Finally, we use matplotlib to display the image. We create a figure with a specified size using `plt.figure(figsize=(10, 8))`.
8. We use `plt.imshow()` to display the logarithmically scaled magnitude image, specifying a grayscale colormap (`cmap='gray'`).
9. We add a colorbar using `plt.colorbar()` to indicate the logarithmic magnitude values.
10. We set the title, x-label (range), and y-label (azimuth) of the plot using `plt.title()`, `plt.xlabel()`, and `plt.ylabel()`, respectively.
11. Finally, we call `plt.show()` to display the plot.
Note: Make sure to replace `'path/to/sentinel1_slc.tiff'` with the actual path to your Sentinel-1 SLC image file.
This code example provides a basic way to read and display a Sentinel-1 SLC image using Python. You can further customize the visualization or perform additional processing on the SLC data based on your specific requirements.
Google Gemini Pro
Please give me a code example for reading and displaying a Sentinel-1 SLC image in Python```
import rasterio
from matplotlib import pyplot as plt
import numpy as np
# Open the Sentinel-1 SLC image
with rasterio.open('path/to/sentinel-1.tif') as src:
# Read the image data
image_data = src.read(1)
# Apply a colour map to the amplitude values
# Image data must be in decibels
color_mapped = plt.cm.viridis(np.log10(image_data))
# Plot the image
fig, ax = plt.subplots(figsize=(10, 10))
ax.imshow(color_mapped)
ax.set_title('Sentinel-1 SLC Image')
plt.show()
```That provided an error though, so…
> Thanks, but the code gave the following error: ```TypeError: Cannot cast array data from dtype('complex64') to dtype('int64') according to the rule 'safe'```he error you are encountering is because the Sentinel-1 SLC image data is complex (i.e. it has real and imaginary components), while the plt.cm.viridis() function expects real-valued data.
To fix this, you can convert the complex data to real-valued data by taking the absolute value:
image_data = np.abs(src.read(1))
Here is the updated code:
import rasterio
from matplotlib import pyplot as plt
import numpy as np
# Open the Sentinel-1 SLC image
with rasterio.open('path/to/sentinel-1.tif') as src:
# Read the image data
image_data = np.abs(src.read(1))
# Apply a colour map to the amplitude values
# Image data must be in decibels
color_mapped = plt.cm.viridis(np.log10(image_data))
# Plot the image
fig, ax = plt.subplots(figsize=(10, 10))
ax.imshow(color_mapped)
ax.set_title('Sentinel-1 SLC Image')
plt.show()
Kimi AI
For Kimi AI I asked in Chinese.
> 请给我一个用 Python 阅读和显示Sentinel-1 SLC 图像的代码示例当然可以。哨Sentinel-1 SLC(Sentinel-1 Single Look Complex)图像是一种合成孔径雷达(SAR)数据,通常用于地球观测和遥感分析。在Python中,可以使用rasterio和sarpy等库来读取和显示Sentinel-1 SLC图像。
以下是一个简单的代码示例,展示了如何使用Python读取Sentinel-1 SLC图像并将其显示出来:
# 首先,确保已经安装了必要的库
# 可以使用pip安装rasterio和sarpy:
# pip install rasterio
# pip install sarpy
import rasterio
from sarpy.io import Sentinel1
from matplotlib import pyplot as plt
# 指定Sentinel-1 SLC图像的路径
slc_image_path = 'path_to_your_sentinel1_slc_image'
# 使用rasterio打开图像
with rasterio.open(slc_image_path) as src:
# 读取图像的第一个波段
image = src.read(1)
# 显示图像
plt.imshow(image, cmap='gray', vmin=-10, vmax=10)
plt.colorbar(label='Intensity (dB)')
plt.title('Sentinel-1 SLC Image')
plt.show()
# 如果是复杂的SLC数据,可以使用sarpy来处理
slc_metadata_path = 'path_to_your_sentinel1_slc_metadata'
# 使用sarpy读取Sentinel-1 SLC元数据
product = Sentinel1.load_product(slc_metadata_path)
# 读取SLC数据
data = product.read()
# 显示SLC数据
plt.imshow(data, cmap='gray', vmin=-10, vmax=10)
plt.colorbar(label='Intensity (dB)')
plt.title('Sentinel-1 SLC Data')
plt.show()
请注意,这个代码示例假设你已经有了Sentinel-1 SLC图像的路径和相应的元数据路径。你需要将path_to_your_sentinel1_slc_image和path_to_your_sentinel1_slc_metadata替换为你的实际文件路径。
在使用这个代码之前,请确保你已经安装了rasterio和sarpy库。这些库可以通过Python的包管理工具pip来安装。此外,由于Sentinel-1 SLC数据可能非常大,因此在处理时可能需要考虑内存管理和性能优化。
What I liked in Kimi is that it used sarpy, a Python library for processing SAR images, that I didn’t know before. But, unfortunately that didn’t work in this example. So, I described the error and asked for changes.
> 谢谢,但出现了以下错误: ```ImportError: cannot import name 'Sentinel1' from 'sarpy.io' ``` 抱歉给您带来了困扰。`sarpy`库中并没有直接名为`Sentinel1`的类或函数。我之前的回答有误,请忽略那个示例。实际上,处理Sentinel-1 SLC数据通常需要使用专门的SAR处理库,如`gdal`、`rasterio`或`sarscape`等。
以下是一个使用`rasterio`和`matplotlib`来读取和显示Sentinel-1 SLC图像的示例代码:
```python
import rasterio
import matplotlib.pyplot as plt
# 指定Sentinel-1 SLC图像的路径
slc_image_path = 'path_to_your_sentinel1_slc_image'
# 使用rasterio打开图像
with rasterio.open(slc_image_path) as src:
# 读取图像的第一个波段(对于SLC数据,通常有多个波段)
image = src.read(1) # 读取第一个波段
# 由于SLC数据是复数,我们需要分别处理实部和虚部
# 这里我们只显示实部作为示例
real_part = image.real
# 显示图像
plt.imshow(real_part, cmap='gray', vmin=-10, vmax=10)
plt.colorbar(label='Intensity (dB)')
plt.title('Real Part of Sentinel-1 SLC Image')
plt.show()
```
请确保你已经安装了`rasterio`和`matplotlib`库。如果没有安装,可以使用以下命令进行安装:
```bash
pip install rasterio matplotlib
```
这个代码示例将读取Sentinel-1 SLC图像的第一个波段的实部,并将其显示为灰度图像。由于SLC数据是复数,包含了幅度和相位信息,这里我们只显示了幅度信息(实部)。
请注意,这个代码示例假设你的Sentinel-1 SLC图像已经是解包(unwrapped)的。如果数据是打包(wrapped)的,你可能需要先进行相位解包。这通常需要更复杂的SAR处理技术和算法。The problem here is that the real part of the completed number is shown and not the absolute.
Baidu Wen Xin (4.0)
This is the paid version. Again, I asked in Chinese.
> 请给我一个用 Python 阅读和显示Sentinel-1 SLC 图像的代码示例Sentinel-1 数据通常以 SAFE (Sentinel Application Platform) 格式分发,该格式是一种特定于 Sentinel 任务的标准数据格式。要读取和显示 Sentinel-1 SLC(单视复图像)数据,我们通常需要使用特定的遥感图像处理库,如 rasterio、GDAL 或 SNAP 的 Python 接口。
以下是一个使用 rasterio 和 matplotlib 库来读取和显示 Sentinel-1 SLC 图像的例子。请注意,Sentinel-1 数据是复数数据,因此我们需要选择如何显示它(例如,显示幅度图像)。
首先,确保你已经安装了必要的库:
bash
pip install rasterio matplotlib numpy
然后,你可以使用以下代码来读取和显示 Sentinel-1 SLC 数据的一个子集(例如,VV 极化):
python
import rasterio
import numpy as np
import matplotlib.pyplot as plt
# 替换为你的 Sentinel-1 SLC 文件的路径
file_path = 'path_to_your_Sentinel-1_SLC_file.tiff' # 例如: 'S1A_IW_SLC__1SDV_20230101T000000_20230101T000959_041969_04FA69_97E8.SAFE/measurement/s1a-iw-slc-vh-20230101t000000-20230101t000959-041969-04fa69-002.tiff'
# 打开文件
with rasterio.open(file_path) as dataset:
# 读取 VV 极化的复数数据 (这取决于你的数据文件如何组织,可能需要调整)
slc_data = dataset.read(1) + 1j * dataset.read(2)
# 计算幅度图像
amplitude = np.abs(slc_data)
# 为了显示,我们可能需要对幅度进行对数缩放,因为雷达数据通常具有较大的动态范围
amplitude_log = 20 * np.log10(amplitude)
# 设置无效的或接近零的值为 NaN,以便在显示时忽略它们
amplitude_log = np.where(amplitude_log <= -30, np.nan, amplitude_log)
# 显示图像
plt.imshow(amplitude_log, cmap='gray', aspect='auto', interpolation='nearest')
plt.colorbar(label='Amplitude [dB]') # 添加颜色条以显示幅度范围
plt.title('Sentinel-1 SLC Amplitude Image')
plt.xlabel('Pixel X')
plt.ylabel('Pixel Y')
plt.show()
注意:上述代码示例假设你的 Sentinel-1 SLC 数据已经过预处理,并且以 TIFF 格式存储,其中包含 VV 和 VH 极化的复数数据作为单独的波段。这通常是通过使用像 ESA SNAP 这样的工具导出数据时得到的格式。根据你的数据文件的确切格式和组织方式,你可能需要调整读取数据的部分。
另外,请确保你有权访问和处理 Sentinel-1 数据,这通常需要注册并遵守 Copernicus Open Access Hub 或其他相关数据源的使用条款和条件。
However, that had an error, as it assumed the data is in two bands. So, I gave the error and asked again.
> 谢谢,但出现了以下错误:```IndexError: band index 2 out of range (not in (1,))```这个错误表明你尝试读取的波段索引超出了数据的范围。对于 Sentinel-1 数据,VV 和 VH 极化通常作为不同的波段存储,但是具体的波段索引可能因产品类型和导出方式而异。
如果你收到 IndexError: band index 2 out of range (not in (1,)) 错误,这意味着你的数据文件可能只包含一个波段,而你尝试读取第二个波段(索引为 2,因为波段索引通常从 1 开始)。
为了解决这个问题,请首先确认你的 Sentinel-1 数据文件中包含哪些波段。你可以使用 rasterio 的 dataset.indexes 属性来查看可用的波段索引。
以下是一个修改后的代码示例,它将首先检查可用的波段,并据此读取数据:
python
import rasterio
import numpy as np
import matplotlib.pyplot as plt
# 替换为你的 Sentinel-1 SLC 文件的路径
file_path = 'path_to_your_Sentinel-1_SLC_file.tiff'
# 打开文件
with rasterio.open(file_path) as dataset:
# 检查可用的波段索引
print("Available bands:", dataset.indexes)
# 假设 VV 极化是第一个波段,VH 极化(如果存在)是第二个波段
vv_data = dataset.read(dataset.indexes[0]) # 读取第一个波段(VV)
vh_data = None
# 如果有两个波段,则读取第二个波段(VH)
if len(dataset.indexes) > 1:
vh_data = dataset.read(dataset.indexes[1]) # 读取第二个波段(VH)
# 如果 VV 和 VH 都存在,则创建复数数据
if vh_data is not None:
slc_data = vv_data + 1j * vh_data
else:
slc_data = vv_data # 否则,只使用 VV 数据
# 计算幅度图像
amplitude = np.abs(slc_data)
# 对数缩放幅度
amplitude_log = 20 * np.log10(amplitude)
amplitude_log = np.where(np.isinf(amplitude_log), -30, amplitude_log) # 将无穷大值替换为 -30 dB
# 显示图像
plt.imshow(amplitude_log, cmap='gray', aspect='auto', interpolation='nearest')
plt.colorbar(label='Amplitude [dB]')
plt.title('Sentinel-1 SLC Amplitude Image')
plt.xlabel('Pixel X')
plt.ylabel('Pixel Y')
plt.show()
在这个修改后的代码中,我们首先打印出可用的波段索引,然后根据这些索引来读取数据。如果数据文件只包含一个波段,我们假设它是 VV 极化,并只使用该波段。如果包含两个波段,我们则读取并使用它们来创建复数数据(VV + 1j * VH)。
请确保根据你的 Sentinel-1 数据文件的实际情况调整代码。Deepseek
This email is running out of space, so just the final result:
```python
import rasterio
import numpy as np
import matplotlib.pyplot as plt
# Open the Sentinel-1 SLC image
with rasterio.open('path_to_your_sentinel1_slc_image.tiff') as src:
# Read the image data
data = src.read()
# Convert complex data to magnitude
magnitude = np.abs(data)
# Display the magnitude image
plt.imshow(magnitude[0], cmap='gray')
plt.colorbar(label='Intensity')
plt.title('Sentinel-1 SLC Magnitude Image')
plt.xlabel('Column #')
plt.ylabel('Row #')
plt.show()
```
Please replace `'path_to_your_sentinel1_slc_image.tiff'` with the actual path to your Sentinel-1 SLC image.
This code reads the image data, computes the magnitude of the complex data using `np.abs`, and then displays the magnitude image using `matplotlib`'s `imshow` function. The `cmap='gray'` parameter is used to display the image in grayscale.
If you want to display the phase of the complex data, you can use `np.angle` instead of `np.abs`:
```python
# Convert complex data to phase
phase = np.angle(data)
# Display the phase image
plt.imshow(phase[0], cmap='hsv')
plt.colorbar(label='Phase')
plt.title('Sentinel-1 SLC Phase Image')
plt.xlabel('Column #')
plt.ylabel('Row #')
plt.show()
```
This will display the phase image in a color map that cycles through the hue values (0 to 2π).
Did also privde code to display the phase image, but the image overall stayed black as the normalization is not correct or it wasn’t converted to dB.









