杰瑞科技汇

Python OpenCV resize如何调整图像尺寸?

Of course! Here is a comprehensive guide on how to resize images using Python and OpenCV, covering the core function, different interpolation methods, and practical examples.

Python OpenCV resize如何调整图像尺寸?-图1
(图片来源网络,侵删)

The Core Function: cv2.resize()

The main function you'll use is cv2.resize(). It has the following signature:

cv2.resize(src, dsize, fx, fy, interpolation)

Let's break down the parameters:

  • src: The source image (the image you want to resize). This is a required parameter.
  • dsize: The desired output size as a tuple (width, height). This is an optional parameter, but if you provide fx and fy, you can set it to (0, 0).
  • fx: (Optional) The scale factor along the horizontal axis (width). If 5, the new width will be half of the original.
  • fy: (Optional) The scale factor along the vertical axis (height). If 5, the new height will be half of the original.
  • interpolation: (Optional) The interpolation algorithm to use. This is crucial for quality.

Basic Resizing Methods

There are two primary ways to resize an image:

Method A: Specifying the Exact Output Size (dsize)

You provide the new width and height directly. This is the most common method.

Python OpenCV resize如何调整图像尺寸?-图2
(图片来源网络,侵删)
import cv2
import numpy as np
# Load an image
image_path = 'your_image.jpg' # Replace with your image path
img = cv2.imread(image_path)
# Check if the image was loaded successfully
if img is None:
    print(f"Error: Could not load image from {image_path}")
else:
    # Get original dimensions
    height, width = img.shape[:2]
    print(f"Original image size: {width}x{height}")
    # Resize to a specific size (e.g., 300x200 pixels)
    # The order is (width, height)
    resized_image = cv2.resize(img, (300, 200))
    # Display the original and resized images
    cv2.imshow('Original Image', img)
    cv2.imshow('Resized Image (300x200)', resized_image)
    cv2.waitKey(0)  # Wait for a key press
    cv2.destroyAllWindows()

Method B: Specifying Scale Factors (fx, fy)

You provide scaling factors for the width and height. The dsize parameter is set to (0, 0) to tell OpenCV to calculate the new size based on the scale factors.

import cv2
# Load an image
image_path = 'your_image.jpg'
img = cv2.imread(image_path)
if img is None:
    print(f"Error: Could not load image from {image_path}")
else:
    # Resize to half the original size
    # fx = 0.5 (scale width by 50%)
    # fy = 0.5 (scale height by 50%)
    resized_image = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
    # Display the original and resized images
    cv2.imshow('Original Image', img)
    cv2.imshow('Resized Image (50%)', resized_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Interpolation Methods (interpolation)

This is one of the most important aspects of resizing. The method you choose affects the quality and speed of the resized image. The choice depends on whether you are enlarging (upsizing) or shrinking (downsizing) the image.

Here are the most common interpolation flags:

Flag Constant Description Best For
cv2.INTER_NEAREST 0 Nearest-neighbor interpolation. Fastest but lowest quality. Speed is critical over quality.
cv2.INTER_LINEAR 1 Bilinear interpolation (default). Good balance of speed and quality. General purpose, a good default.
cv2.INTER_CUBIC 2 Bicubic interpolation over a 4x4 pixel neighborhood. Slower but higher quality. Upsizing (Enlarging) images.
cv2.INTER_LANCZOS4 4 Lanczos interpolation over an 8x8 pixel neighborhood. Highest quality. Upsizing (Enlarging) images for the best quality.
cv2.INTER_AREA 3 Resampling using pixel area relation. It may be a preferred method for image decimation (downsampling). Downsizing (Shrinking) images. This avoids "aliasing" artifacts.

Example: Comparing Interpolation Methods

Let's see the difference when upsizing an image.

Python OpenCV resize如何调整图像尺寸?-图3
(图片来源网络,侵删)
import cv2
import numpy as np
# Load a small image to enlarge
image_path = 'small_image.jpg' # Use a small image for this demo
img = cv2.imread(image_path)
if img is None:
    print(f"Error: Could not load image from {image_path}")
else:
    # --- Upsizing (Enlarging) ---
    # Scale to double the size
    scale_percent = 200  # percent of original size
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    # Resize using different interpolation methods
    res_inter_nearest = cv2.resize(img, dim, interpolation=cv2.INTER_NEAREST)
    res_inter_linear = cv2.resize(img, dim, interpolation=cv2.INTER_LINEAR) # Default
    res_inter_cubic = cv2.resize(img, dim, interpolation=cv2.INTER_CUBIC)
    res_inter_lanczos = cv2.resize(img, dim, interpolation=cv2.INTER_LANCZOS4)
    # --- Downsizing (Shrinking) ---
    # Scale to half the size
    scale_percent = 50
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    # Resize using different interpolation methods
    res_inter_area = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
    res_inter_linear_down = cv2.resize(img, dim, interpolation=cv2.INTER_LINEAR)
    # Display the results
    cv2.imshow('Original', img)
    cv2.imshow('INTER_NEAREST (Upsized)', res_inter_nearest)
    cv2.imshow('INTER_LINEAR (Upsized)', res_inter_linear)
    cv2.imshow('INTER_CUBIC (Upsized)', res_inter_cubic)
    cv2.imshow('INTER_LANCZOS4 (Upsized)', res_inter_lanczos)
    cv2.imshow('INTER_AREA (Downsized)', res_inter_area)
    cv2.imshow('INTER_LINEAR (Downsized)', res_inter_linear_down)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Key Takeaways from the example:

  • For enlarging, INTER_CUBIC and INTER_LANCZOS4 produce much smoother results than INTER_NEAREST.
  • For shrinking, INTER_AREA is generally recommended to produce a cleaner, less aliased result than INTER_LINEAR.

Maintaining Aspect Ratio

A very common requirement is to resize an image to fit within a certain box while maintaining its original aspect ratio. Here's how to do it.

import cv2
def resize_with_aspect_ratio(image, width=None, height=None, inter=cv2.INTER_AREA):
    """
    Resizes an image while maintaining its aspect ratio.
    """
    dim = None
    (h, w) = image.shape[:2]
    if width is None and height is None:
        return image
    if width is None:
        # Calculate the ratio of the height and construct the
        # dimensions
        r = height / float(h)
        dim = (int(w * r), height)
    else:
        # Calculate the ratio of the width and construct the
        # dimensions
        r = width / float(w)
        dim = (width, int(h * r))
    # Resize the image
    resized = cv2.resize(image, dim, interpolation=inter)
    # Return the resized image
    return resized
# --- Example Usage ---
image_path = 'your_image.jpg'
img = cv2.imread(image_path)
if img is None:
    print(f"Error: Could not load image from {image_path}")
else:
    # Resize to a max width of 400px, maintaining aspect ratio
    resized_to_width = resize_with_aspect_ratio(img, width=400)
    print(f"Resized to width 400: {resized_to_width.shape[1]}x{resized_to_width.shape[0]}")
    # Resize to a max height of 300px, maintaining aspect ratio
    resized_to_height = resize_with_aspect_ratio(img, height=300)
    print(f"Resized to height 300: {resized_to_height.shape[1]}x{resized_to_height.shape[0]}")
    cv2.imshow('Original', img)
    cv2.imshow('Resized to Max Width 400', resized_to_width)
    cv2.imshow('Resized to Max Height 300', resized_to_height)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Summary of Best Practices

Task Recommended Interpolation Method Why?
General Purpose cv2.INTER_LINEAR Good balance of speed and quality for most cases.
Enlarging an Image cv2.INTER_CUBIC or cv2.INTER_LANCZOS4 These methods use more neighboring pixels to create smoother, higher-quality results when increasing the image size.
Shrinking an Image cv2.INTER_AREA This method is specifically designed to reduce aliasing artifacts that occur when you remove pixels. It produces the best quality for downsampling.
Fastest Resizing cv2.INTER_NEAREST It's the fastest because it just copies the nearest pixel. Use this only when speed is more important than visual quality.
分享:
扫描分享到社交APP
上一篇
下一篇