杰瑞科技汇

Python imreadmulti如何批量读取图像?

Of course! The term imreadmulti is not a standard function in the core Python libraries (like the standard PIL/Pillow or scikit-image). However, it is a very common name for a function that users need to write or that exists in specialized toolkits.

Python imreadmulti如何批量读取图像?-图1
(图片来源网络,侵删)

The goal of an imreadmulti function is to read all images from a multi-page file format (like TIFF or GIF) or all images from a series of similarly named files (like image_001.png, image_002.png, etc.).

Here’s a complete guide covering the different scenarios and how to implement the functionality, from the most common methods to writing your own custom function.


The Most Common Case: Reading Multi-Page TIFF Files

The most frequent use case for "imreadmulti" is reading a TIFF file that contains multiple images (or frames) in a single file. For this, the best library is imageio.

Solution using imageio

imageio is a powerful library for reading and writing a wide range of image data, including multi-page formats.

Python imreadmulti如何批量读取图像?-图2
(图片来源网络,侵删)

Installation:

pip install imageio

Code:

import imageio
import matplotlib.pyplot as plt
# Path to your multi-page TIFF file
# You can create one for testing with: imageio.mimwrite('test_multi.tif', [image1, image2, image3])
file_path = 'path/to/your/multi_image.tif'
try:
    # imageio.imread() is deprecated, use imageio.mimread() for multi-page images
    images = imageio.mimread(file_path)
    print(f"Successfully read {len(images)} images from '{file_path}'")
    print(f"Shape of the first image: {images[0].shape}")
    # Let's display the first and second frames
    plt.figure(figsize=(10, 5))
    plt.subplot(1, 2, 1)
    plt.imshow(images[0])
    plt.title("Frame 1")
    plt.axis('off')
    plt.subplot(1, 2, 2)
    plt.imshow(images[1])
    plt.title("Frame 2")
    plt.axis('off')
    plt.tight_layout()
    plt.show()
except FileNotFoundError:
    print(f"Error: The file '{file_path}' was not found.")
except Exception as e:
    print(f"An error occurred: {e}")

Explanation:

  • imageio.mimread() is the key function. It automatically detects if a file is multi-page and reads all the frames into a Python list.
  • The images variable becomes a list of NumPy arrays, where each array is one frame of the multi-page image.

Alternative: Reading Multi-Page TIFF with tifffile

The tifffile library is a highly optimized library specifically for TIFF files. It's often faster and more feature-rich for TIFFs than imageio.

Python imreadmulti如何批量读取图像?-图3
(图片来源网络,侵删)

Installation:

pip install tifffile

Code:

import tifffile
import matplotlib.pyplot as plt
file_path = 'path/to/your/multi_image.tif'
try:
    # tifffile.imread() can read all pages by default
    images = tifffile.imread(file_path)
    print(f"Successfully read {len(images)} images from '{file_path}'")
    print(f"Shape of the image stack: {images.shape}") # Will be (num_frames, height, width)
    # Display the first frame
    plt.imshow(images[0])
    plt.title("First Frame from tifffile")
    plt.axis('off')
    plt.show()
except FileNotFoundError:
    print(f"Error: The file '{file_path}' was not found.")
except Exception as e:
    print(f"An error occurred: {e}")

Explanation:

  • tifffile.imread() is incredibly simple. If the TIFF file has multiple pages, it returns a NumPy array with an extra dimension for the frames (e.g., (frames, height, width, channels)).
  • This is often more convenient for processing, as you don't have to index a list.

Case: Reading a Series of Single Files (e.g., img_001.png)

Sometimes, "imreadmulti" refers to loading a sequence of images that are individual files, often named with a numbering scheme (e.g., from a video or a microscope scan).

Solution using glob and Pillow (PIL)

The glob module is perfect for finding files that match a specific pattern, and Pillow is the standard for basic image manipulation in Python.

Installation:

pip install Pillow

Code:

import glob
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
# Create a list of file paths using a glob pattern
# This pattern looks for all .png files starting with 'image_' and ending with '_###.png'
file_pattern = 'path/to/your/images/image_*.png'
file_paths = sorted(glob.glob(file_pattern))
print(f"Found {len(file_paths)} image files.")
if not file_paths:
    print("No files found matching the pattern.")
else:
    # Read all images into a list
    images = [Image.open(f) for f in file_paths]
    # If you need them as NumPy arrays:
    image_arrays = [np.array(img) for img in images]
    print(f"Shape of the first image array: {image_arrays[0].shape}")
    # Display the first image from the sequence
    plt.imshow(image_arrays[0])
    plt.title(f"First Image: {file_paths[0]}")
    plt.axis('off')
    plt.show()

Explanation:

  • glob.glob(file_pattern) finds all files that match the pattern. Using sorted() is crucial to ensure the images are loaded in the correct order.
  • We use a list comprehension [Image.open(f) for f in file_paths] to efficiently open all the files.
  • Converting them to NumPy arrays with np.array() is a common next step for analysis.

Creating Your Own imreadmulti Function

You can easily wrap the logic from above into a single, reusable function. This is great for making your code cleaner.

Here is a robust function that tries different methods:

import numpy as np
import glob
import os
from typing import Union, List
def imreadmulti(
    source: str,
    as_numpy: bool = True,
    sort: bool = True
) -> Union[List[Image.Image], List[np.ndarray]]:
    """
    Reads multiple images from a multi-page file or a series of single files.
    Args:
        source (str): The path to a multi-page image file (e.g., .tiff, .gif)
                      or a directory/glob pattern for a series of images.
        as_numpy (bool): If True, returns images as NumPy arrays. Otherwise,
                         returns them as PIL Image objects. Defaults to True.
        sort (bool): If True, sorts the file paths lexicographically before reading.
                     Defaults to True.
    Returns:
        A list of image objects (either NumPy arrays or PIL Images).
    """
    images = []
    # Case 1: Source is a file (try to read as multi-page)
    if os.path.isfile(source):
        try:
            # Try with tifffile first (fast and specific)
            import tifffile
            images = tifffile.imread(source)
            # tifffile returns a numpy array, so we might need to convert to list
            if images.ndim > 3 or (images.ndim == 3 and images.shape[0] < 10 and images.shape[1] > 100):
                 # Heuristic: if it looks like (frames, h, w), convert to list of frames
                images = [images[i, ...] for i in range(images.shape[0])]
            elif images.ndim == 2: # Single page tiff
                images = [images]
            print(f"Successfully read {len(images)} frames using tifffile.")
            return images if as_numpy else [Image.fromarray(img) for img in images]
        except ImportError:
            print("tifffile not found, trying imageio...")
            try:
                # Fallback to imageio
                import imageio
                images = imageio.mimread(source)
                print(f"Successfully read {len(images)} frames using imageio.")
                return images if as_numpy else [Image.fromarray(img) for img in images]
            except Exception as e:
                print(f"Could not read multi-page file '{source}': {e}")
                return [] # Return empty list on failure
    # Case 2: Source is a glob pattern or directory
    elif os.path.isdir(source) or '*' in source or '?' in source:
        if os.path.isdir(source):
            # If it's a directory, assume all files are images
            file_pattern = os.path.join(source, '*')
        else:
            file_pattern = source
        file_paths = glob.glob(file_pattern)
        if sort:
            file_paths.sort()
        if not file_paths:
            print(f"No files found for pattern: '{file_pattern}'")
            return []
        for f_path in file_paths:
            try:
                img = Image.open(f_path)
                if as_numpy:
                    images.append(np.array(img))
                else:
                    images.append(img)
            except Exception as e:
                print(f"Could not read image '{f_path}': {e}")
        print(f"Successfully read {len(images)} images from a sequence.")
        return images
    else:
        print(f"Error: Source '{source}' is not a valid file or directory/glob pattern.")
        return []
# --- Example Usage ---
# Example 1: Using a multi-page TIFF (assuming you have one)
# First, let's create a dummy multi-page tiff for the example to run
try:
    import imageio
    img1 = np.zeros((100, 100, 3), dtype=np.uint8)
    img2 = np.ones((100, 100, 3), dtype=np.uint8) * 128
    img3 = np.full((100, 100, 3), 255, dtype=np.uint8)
    imageio.mimwrite('my_multipage.tif', [img1, img2, img3])
    print("Created dummy 'my_multipage.tif' for demonstration.\n")
    # Now use the function
    multi_page_images = imreadmulti('my_multipage.tif')
    print(f"Loaded {len(multi_page_images)} frames from TIFF.\n")
except ImportError:
    print("imageio not installed, skipping TIFF creation/example.\n")
# Example 2: Using a series of PNG files
# Create dummy files for the example
for i in range(3):
    img = Image.fromarray(np.random.randint(0, 255, (50, 50, 3), dtype=np.uint8))
    img.save(f'series_image_{i:03d}.png')
print("Created dummy 'series_image_*.png' files for demonstration.\n")
# Now use the function
sequence_images = imreadmulti('series_image_*.png')
print(f"Loaded {len(sequence_images)} images from a sequence.")
print(f"Shape of the first image in the sequence: {sequence_images[0].shape}")
# Clean up dummy files
os.remove('my_multipage.tif')
for i in range(3):
    os.remove(f'series_image_{i:03d}.png')

Summary: Which one should you use?

Scenario Recommended Library Why?
Multi-Page TIFF tifffile Fastest, most feature-rich, and idiomatic for TIFF files. Returns a convenient N-d array.
Multi-Page TIFF imageio Excellent alternative, supports more formats than just TIFF (e.g., GIF, DICOM). Very easy to use.
Image Sequence glob + Pillow Standard, robust, and flexible. Works for any image format supported by Pillow.
Custom Function Wrap one of the above For cleaner code and handling different input types (file vs. sequence) in one place.
分享:
扫描分享到社交APP
上一篇
下一篇