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

如何在Python PyQt5中解决高光谱图像嵌入QLabel的报错问题

问题:QPixmap嵌入高光谱图像到QLabel失败

在Qt界面中,将普通图像用QPixmap嵌入QLabel完全正常,但嵌入处理后的高光谱图像时出现错误。使用rasterio处理高光谱图像的代码如下:

img = rs.open('HYP.tif')
profile = img.profile

profile.update(count=3, compress='lzw')

full_img = img.read()

band1 = int(input('band number 1:'))
band2 = int(input('band number 2:'))
band3 = int(input('band number 3:'))

b1 = img.read(band1)
b2 = img.read(band2)
b3 = img.read(band3)

def normalize(array):
    #Normalizes numpy arrays into scale 0.0 - 1.0
    array_min, array_max = array.min(), array.max()
    return (array - array_min) / (array_max - array_min)

# Normalize the bands
redn = normalize(b3)
greenn = normalize(b2)
bluen = normalize(b1)

rgb = np.dstack((bluen, redn, greenn))

rgb1 = rgb.T
rasterio.plot.show(rgb1)

rgb3 = rgb1 / rgb1.max()
rgb3 = rgb3 * 255
rgb3 = rgb3.astype(numpy.uint32)
rasterio.plot.show(rgb3)

file_list = [rgb1.read, greenn, bluen]
with rs.open('outimg.png', 'w', **profile) as dest:
    for band_nr, src in enumerate(file_list, start=1):
        dest.write(src, band_nr)

self.label_2.setPixmap(QtGui.QPixmap('outimg.png'))

执行self.label_2.setPixmap(QtGui.QPixmap('outimg.png'))时,报错:

foo: Sorry, can not handle images with 32-bit samples.

错误原因

  1. 格式不兼容:Qt的QPixmap仅支持单通道8位的RGB/RGBA图像(总像素深度24位或32位),而你生成的outimg.png是单通道32位采样的图像,超出了QPixmap的支持范围。
  2. 代码数据处理错误:
    • 你将rgb3转成了uint32,但后续保存时并没有使用这个数据,反而误用了rgb1.read(这是rasterio的读取方法,不是实际图像数据)和归一化后的0-1浮点数数组,导致保存的图像格式不符合要求。
    • 更新profile时未调整dtype,原高光谱图像的高位深度被保留,最终输出的图像还是32位采样。

解决方法

方法1:修正保存流程,生成符合要求的8位RGB图像

import rasterio as rs
import numpy as np
from PyQt5 import QtGui

# 读取高光谱图像
img = rs.open('HYP.tif')
band1 = int(input('band number 1:'))
band2 = int(input('band number 2:'))
band3 = int(input('band number 3:'))

# 读取指定波段
b1 = img.read(band1)
b2 = img.read(band2)
b3 = img.read(band3)

def normalize(array):
    # 归一化到0-1范围
    array_min, array_max = array.min(), array.max()
    return (array - array_min) / (array_max - array_min)

# 归一化各波段
redn = normalize(b3)
greenn = normalize(b2)
bluen = normalize(b1)

# 组合为RGB图像并转换为0-255的8位无符号整数
rgb = np.dstack((bluen, redn, greenn)) * 255
rgb = rgb.astype(np.uint8)

# 构建新的profile,指定8位格式和PNG驱动
profile = img.profile.copy()
profile.update(
    count=3,
    dtype=np.uint8,
    compress='lzw',
    driver='PNG'
)

# 转换为rasterio要求的(C, H, W)通道顺序
rgb_raster = np.transpose(rgb, (2, 0, 1))

# 保存图像
with rs.open('outimg.png', 'w', **profile) as dest:
    dest.write(rgb_raster)

# 加载到QLabel
self.label_2.setPixmap(QtGui.QPixmap('outimg.png'))

方法2:直接将numpy数组转成QPixmap(无需存文件,更高效)

在得到rgb(uint8类型的(H,W,3)数组)后,直接转换:

height, width, channel = rgb.shape
bytes_per_line = channel * width
# 转成QImage
q_image = QtGui.QImage(rgb.data, width, height, bytes_per_line, QtGui.QImage.Format_RGB888)
# 转成QPixmap并设置
self.label_2.setPixmap(QtGui.QPixmap.fromImage(q_image))

关键修正点

  • 必须将图像数据转换为np.uint8(0-255范围),确保单通道是8位采样。
  • 保存图像时,profile要指定dtype=np.uint8,同时调整通道顺序为rasterio要求的(C, H, W)。
  • 避免使用uint32这类QPixmap不支持的高位深度类型。

内容的提问来源于stack exchange,提问作者Shivanshika Chauhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:55:25