如何在Tkinter中基于树莓派热成像相机的整数数组显示彩色图像
Solution: Display Thermal Camera Data as Colored Image in Tkinter
Got it, let's fix this step by step. The core issue here is mapping your raw thermal integer values to a colorful thermal gradient (like purple → red → yellow) and converting that into a format Tkinter can display. Here's a complete, working approach tailored to your 32×24 resolution data:
Key Steps Breakdown
- Reshape your 1D list: Convert your 768-element integer list into a 24×32 NumPy array (since 24×32=768).
- Normalize data: Thermal values are likely outside the 0-255 range that colormaps use—we’ll scale them to fit this range for proper color mapping.
- Apply a thermal colormap: Use a pre-built colormap (like
inferno, which has the classic thermal color gradient) to turn grayscale values into RGB colors. - Convert to Tkinter PhotoImage: Pack the RGB data into a PPM format (natively supported by Tkinter) and display it.
Full Working Code
import tkinter as tk import numpy as np from matplotlib import cm from matplotlib.colors import Normalize def thermal_to_photo(thermal_array, cmap_name='inferno'): # Normalize thermal data to 0-255 range (adjust vmin/vmax if you know your temp bounds) norm = Normalize(vmin=np.min(thermal_array), vmax=np.max(thermal_array)) # Apply the colormap to get RGB values colored_data = cm.get_cmap(cmap_name)(norm(thermal_array)) # Convert to 8-bit RGB (discard alpha channel if present) rgb_array = (colored_data[:, :, :3] * 255).astype(np.uint8) # Get image dimensions height, width = rgb_array.shape[:2] # Create PPM header (P6 is binary color PPM format) ppm_header = f'P6 {width} {height} 255 '.encode() # Combine header with raw RGB bytes ppm_data = ppm_header + rgb_array.tobytes() # Return Tkinter PhotoImage return tk.PhotoImage(width=width, height=height, data=ppm_data, format='PPM') # Initialize Tkinter window root = tk.Tk() root.title("Raspberry Pi Thermal Camera") # Replace this with your actual 768-element integer list # Example: Simulate thermal values (e.g., 20-40°C scaled by 100) thermal_1d_list = np.random.randint(2000, 4000, size=768).tolist() # Convert 1D list to 24x32 array thermal_2d_array = np.array(thermal_1d_list).reshape(24, 32) # Generate the colored photo image thermal_image = thermal_to_photo(thermal_2d_array) # Display using a Label (simpler than Canvas for static images) image_label = tk.Label(root, image=thermal_image) image_label.pack(padx=10, pady=10) # Critical: Keep a reference to the image to prevent garbage collection image_label.image = thermal_image root.mainloop()
Customization Tips
- Colormap Choice: Swap
'inferno'with other thermal-friendly options like'plasma'(purple → pink → yellow) or'magma'(black → purple → red → yellow) to get different color gradients. - Fixed Temperature Range: If you know the min/max possible temperatures (e.g., 10°C to 50°C), replace
vmin=np.min(thermal_array)andvmax=np.max(thermal_array)with your actual scaled values (likevmin=1000,vmax=5000if you’re scaling by 100). This ensures consistent color mapping across frames, even if the temperature range shifts. - Image Scaling: To get a larger view, resize the RGB array using
cv2.resize(install OpenCV first) or use Tkinter’sPhotoImage.zoom()method—note that resizing will make the low-res 32×24 image pixelated.
Why Your Original Code Didn’t Work
The StackOverflow color code relied on OpenCV’s BGR-to-RGB conversion, but it required a 3-channel RGB input (not your single-channel thermal array). Our approach directly maps your raw thermal data to RGB using a colormap, which is exactly what you need for thermal imaging.
内容的提问来源于stack exchange,提问作者Will Jordan
相关产品推荐
相关产品推荐

