You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TIF格式Landsat-9影像无法在Tkinter界面正常显示求助

问题:CustomTkinter加载Landsat-9 TIF影像显示空白(PNG可正常显示)

你的问题核心是遥感TIF影像的位深和波段结构不被CustomTkinter的CTkImage直接支持:Landsat-9的TIF大多是16位灰度/多波段影像,而CTkImage仅支持8位的RGB/RGBA格式,直接用PIL打开会因格式不兼容显示空白,PNG因为是8位格式所以正常。

解决方案

需要先将遥感TIF转换为CTkImage支持的8位RGB格式,这里用rasterio处理遥感影像,numpy做数值转换,步骤如下:

  1. 安装依赖库
pip install rasterio numpy
  1. 修改代码如下(注释标注关键改动):
from tkinter import *
import os
import customtkinter as ctk
from PIL import Image
import rasterio
import numpy as np

# 统一路径,避免相对/绝对路径不一致
IMAGE_DIR = r"C:\Users\Shahriar\Documents\WorkSpace\RS\Landsat-9"
Image_Names = sorted(os.listdir(IMAGE_DIR), key=len)

ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("dark-blue")

Window = ctk.CTk()
Window.title("RS")
Window.iconbitmap("./Satellite.ico")
Window.geometry("1280x720")

Frame = ctk.CTkFrame(Window, width=820, height=820)

def clear_frame():
    for widgets in Frame.winfo_children():
        widgets.destroy()

def normalize_16bit_to_8bit(arr):
    """将16位遥感影像数值拉伸到0-255的8位范围"""
    arr_min = arr.min()
    arr_max = arr.max()
    if arr_max == arr_min:
        return np.zeros(arr.shape, dtype=np.uint8)
    return ((arr - arr_min) / (arr_max - arr_min) * 255).astype(np.uint8)

def OpenImage(choice):
    clear_frame()
    global image, final_Image
    img_path = os.path.join(IMAGE_DIR, choice)
    
    # 判断是否为TIF文件
    if choice.lower().endswith(".tif") or choice.lower().endswith(".tiff"):
        with rasterio.open(img_path) as src:
            # 处理多波段(取Landsat-9的RGB组合:4=红,3=绿,2=蓝)
            if src.count >=3:
                red = normalize_16bit_to_8bit(src.read(4))
                green = normalize_16bit_to_8bit(src.read(3))
                blue = normalize_16bit_to_8bit(src.read(2))
                # 合并为RGB图像
                rgb_arr = np.dstack((red, green, blue))
                image = Image.fromarray(rgb_arr)
            # 处理单波段影像
            else:
                single_band = normalize_16bit_to_8bit(src.read(1))
                image = Image.fromarray(single_band).convert("RGB")
    else:
        # 非TIF文件用原方式打开
        image = Image.open(img_path)
    
    final_Image = ctk.CTkImage(dark_image=image, size=(800, 800))
    Label = ctk.CTkLabel(Frame, text="", image=final_Image)
    Label.pack(pady=10)

Combo_Img = ctk.CTkComboBox(Window, values=Image_Names, command=OpenImage)
Combo_Img.pack(pady=10)
Frame.pack(pady=10, expand=True)

Window.mainloop()

关键说明

  • 位深转换:normalize_16bit_to_8bit函数把16位遥感影像的数值范围拉伸到0-255,适配CTkImage的8位要求;
  • 波段处理:Landsat-9的标准RGB组合是4、3、2波段(对应可见光红、绿、蓝),如果你的影像波段顺序不同,可自行调整读取的波段索引;
  • 路径统一:用os.path.join拼接路径,避免相对路径和绝对路径不一致导致的文件找不到问题;
  • 兼容非TIF:保留了原有的PNG等格式支持逻辑。

内容的提问来源于stack exchange,提问作者shahriar.n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:27:42