杰瑞科技汇

Shape在OpenCV Python中如何使用?

Of course! The shape attribute in OpenCV (and NumPy) is one of the most fundamental and frequently used properties. It tells you the dimensions of an array, which, in the context of images, means its height, width, and number of color channels.

Shape在OpenCV Python中如何使用?-图1
(图片来源网络,侵删)

Let's break it down in detail.

What is the shape Attribute?

The shape attribute is a property of a NumPy array. Since OpenCV stores images as NumPy arrays, every image object you load or create in OpenCV has a shape attribute.

It returns a tuple representing the array's dimensions. The order of these dimensions is crucial:

(height, width, channels) for color images. (height, width) for grayscale images.

Shape在OpenCV Python中如何使用?-图2
(图片来源网络,侵删)

Let's break down that tuple:

  • height: The number of pixels in the vertical direction. This is the first element in the tuple.
  • width: The number of pixels in the horizontal direction. This is the second element.
  • channels: The number of color channels. This is the third element, but only exists for color images.
    • For a BGR image (OpenCV's default), this is 3.
    • For an RGBA image (with an alpha/transparency channel), this is 4.
    • For a grayscale image, this dimension is absent.

Practical Examples

Let's see shape in action with different types of images.

Setup: Loading an Image

First, make sure you have an image file. Let's use the popular lena.jpg or messi5.jpg from the OpenCV samples. You can download them or use your own.

import cv2
import numpy as np
# Try to load a sample image. If it fails, create a sample one.
try:
    # Load a color image
    image_path = 'messi5.jpg' # Replace with your image path
    img_color = cv2.imread(image_path)
    if img_color is None:
        raise FileNotFoundError(f"Could not read image at {image_path}")
except (FileNotFoundError, NameError):
    print("Sample image not found. Creating a sample 300x400 BGR image.")
    # Create a sample image if the file is not found
    img_color = np.zeros((300, 400, 3), dtype=np.uint8)
    img_color[:, :200] = (255, 0, 0)   # Left half: Blue
    img_color[:, 200:] = (0, 255, 0)   # Right half: Green

Example 1: Shape of a Color Image

A color image has 3 channels (Blue, Green, Red in OpenCV).

Shape在OpenCV Python中如何使用?-图3
(图片来源网络,侵删)
# Get the shape of the color image
shape_color = img_color.shape
print(f"Image object type: {type(img_color)}")
print(f"Color image shape: {shape_color}")
print(f"Height: {shape_color[0]} pixels")
print(f"Width: {shape_color[1]} pixels")
print(f"Channels: {shape_color[2]}")
# Expected Output (for a typical image):
# Image object type: <class 'numpy.ndarray'>
# Color image shape: (342, 548, 3)
# Height: 342 pixels
# Width: 548 pixels
# Channels: 3

Example 2: Shape of a Grayscale Image

When you convert a color image to grayscale, the channel dimension disappears.

# Convert the color image to grayscale
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)
# Get the shape of the grayscale image
shape_gray = img_gray.shape
print(f"\nGrayscale image shape: {shape_gray}")
print(f"Height: {shape_gray[0]} pixels")
print(f"Width: {shape_gray[1]} pixels")
# Note: There is no 'channels' dimension here.
# Expected Output:
# Grayscale image shape: (342, 548)
# Height: 342 pixels
# Width: 548 pixels

Example 3: Shape of a Black/White (Binary) Image

A binary image is also a single-channel image, just like grayscale. The values are typically just 0 (black) and 255 (white).

# Create a binary image (thresholding the grayscale image)
# Pixels with value > 127 become white (255), others become black (0)
_, img_binary = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
# Get the shape
shape_binary = img_binary.shape
print(f"\nBinary image shape: {shape_binary}")
print(f"Height: {shape_binary[0]} pixels")
print(f"Width: {shape_binary[1]} pixels")
# Expected Output:
# Binary image shape: (342, 548)
# Height: 342 pixels
# Width: 548 pixels

Common Use Cases for shape

Knowing the shape of your image is essential for many tasks.

a) Looping Through Pixels

If you need to process every pixel, shape tells you the bounds for your loops.

# Get dimensions for a grayscale image
height, width = img_gray.shape
print("\n--- Looping through pixels ---")
# Loop through rows (height)
for y in range(height):
    # Loop through columns (width)
    for x in range(width):
        # Access the pixel value at (x, y)
        pixel_value = img_gray[y, x]
        # You can do something with the pixel_value here
        # For example, let's find the brightest pixel
        if y == 0 and x == 0:
            max_val = pixel_value
            max_loc = (x, y)
        else:
            if pixel_value > max_val:
                max_val = pixel_value
                max_loc = (x, y)
print(f"The brightest pixel has a value of {max_val} at location {max_loc}")

b) Resizing an Image

When you resize an image, you are changing its shape. The cv2.resize() function is a perfect example.

# Resize the color image to half its size
# Get the original dimensions
h, w = img_color.shape[:2] # Use [:2] to work for both color and grayscale
# Calculate new dimensions
new_width = w // 2
new_height = h // 2
# Resize the image
img_resized = cv2.resize(img_color, (new_width, new_height))
print(f"\nOriginal image shape: {img_color.shape}")
print(f"Resized image shape: {img_resized.shape}")

c) Cropping an Image (Image Slicing)

You can crop an image by slicing the NumPy array, and shape helps you define the region of interest (ROI).

# Crop a 100x100 pixel region from the top-left corner
# The slice is [y_start:y_end, x_start:x_end]
roi = img_color[0:100, 0:100]
print(f"\nOriginal image shape: {img_color.shape}")
print(f"Cropped ROI shape: {roi.shape}")

d) Checking Image Properties Before Processing

Before performing an operation that requires a specific image type (e.g., finding contours), you should check the shape to ensure it's a single-channel image.

# Example: Find contours (requires a single-channel, binary image)
def find_largest_contour(image):
    """Finds and returns the largest contour in a binary image."""
    # Check if the image is binary (2D shape)
    if len(image.shape) > 2:
        print("Error: Image must be grayscale/binary to find contours.")
        return None
    contours, _ = cv2.findContours(image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    if not contours:
        return None
    # Find the largest contour by area
    largest_contour = max(contours, key=cv2.contourArea)
    return largest_contour
# This will work
largest_contour_gray = find_largest_contour(img_binary)
if largest_contour_gray is not None:
    print("\nFound largest contour in the binary image.")
# This will print an error message
largest_contour_color = find_largest_contour(img_color)

shape vs. size vs. dtype

It's easy to confuse shape with other NumPy array attributes.

Attribute Description Example with img_color (shape (342, 548, 3))
shape A tuple of the array's dimensions (height, width, channels). (342, 548, 3)
size An integer for the total number of elements in the array (height width channels). 342 * 548 * 3 = 562,248
dtype The data type of the array's elements (e.g., uint8, float32). uint8 (standard for images)
print(f"\n--- Other Image Properties ---")
print(f"Image shape: {img_color.shape}")
print(f"Image size (total pixels): {img_color.size}")
print(f"Image data type: {img_color.dtype}")

Summary

Image Type shape Output Explanation
Color (BGR) (h, w, 3) Height, Width, and 3 color channels.
Grayscale (h, w) Height and Width. No channel dimension.
Binary (h, w) Same as grayscale, a single-channel image.

Mastering the shape attribute is the first step to effectively manipulating and analyzing images with OpenCV and Python. It's your go-to tool for understanding the fundamental structure of your image data.

分享:
扫描分享到社交APP
上一篇
下一篇