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

Eigen3矩阵缩放实现:类似OpenCV cv::resize的插值缩放方法

How to Scale a 1000×1000 Eigen3 Matrix to 2000×2000 with Interpolation

Great question! Unlike OpenCV which has a ready-to-use cv::resize function for image scaling, Eigen3 doesn't include an out-of-the-box equivalent for its core Matrix type. However, you can easily implement interpolation-based scaling yourself, or use Eigen's Tensor module if you're working with image-like data. Here are two reliable approaches:

1. Manual Bilinear Interpolation (For Core Eigen Matrix Types)

Bilinear interpolation is a common choice for smooth scaling, and works well for any scaling factor (not just integer multiples like 2x). Here's a complete implementation:

#include <Eigen/Dense>
#include <cmath>
#include <algorithm>

Eigen::MatrixXd scaleMatrix(const Eigen::MatrixXd& input, double scale) {
    const int inputRows = input.rows();
    const int inputCols = input.cols();
    const int outputRows = static_cast<int>(inputRows * scale);
    const int outputCols = static_cast<int>(inputCols * scale);
    
    Eigen::MatrixXd output(outputRows, outputCols);
    
    for (int y = 0; y < outputRows; ++y) {
        for (int x = 0; x < outputCols; ++x) {
            // Map target pixel to original matrix coordinates
            const double srcY = y / scale;
            const double srcX = x / scale;
            
            // Get surrounding integer coordinates (clamped to avoid out-of-bounds)
            const int y0 = static_cast<int>(std::floor(srcY));
            const int y1 = std::min(y0 + 1, inputRows - 1);
            const int x0 = static_cast<int>(std::floor(srcX));
            const int x1 = std::min(x0 + 1, inputCols - 1);
            
            // Calculate fractional offsets
            const double dy = srcY - y0;
            const double dx = srcX - x0;
            
            // Bilinear interpolation formula
            const double interpolatedValue = 
                (1.0 - dx) * (1.0 - dy) * input(y0, x0) +
                dx * (1.0 - dy) * input(y0, x1) +
                (1.0 - dx) * dy * input(y1, x0) +
                dx * dy * input(y1, x1);
            
            output(y, x) = interpolatedValue;
        }
    }
    
    return output;
}

// Usage Example
int main() {
    // Create a 1000x1000 random matrix
    Eigen::MatrixXd originalMatrix = Eigen::MatrixXd::Random(1000, 1000);
    
    // Scale to 2000x2000 (scale factor = 2.0)
    Eigen::MatrixXd scaledMatrix = scaleMatrix(originalMatrix, 2.0);
    
    return 0;
}

Key Notes:

  • Boundary Handling: We use std::min to clamp coordinates to the original matrix's bounds, preventing out-of-bounds access.
  • Flexibility: This works for any positive scale factor (e.g., 0.5x for downscaling, 3.2x for arbitrary upscaling).
  • Performance: For large matrices, you might want to optimize this with vectorization (Eigen's auto-vectorization can help if you compile with optimizations enabled).

2. Using Eigen's Tensor Module (For Image/Tensor Data)

If you're working with data that's naturally tensor-like (like images), Eigen's Tensor module provides built-in interpolation utilities. This is cleaner if you can enable the Tensor module in your Eigen build:

#include <Eigen/Tensor>

using namespace Eigen;

// Scale a 2D tensor with bilinear interpolation
Tensor<double, 2> scaleTensor(const Tensor<double, 2>& input, double scale) {
    const int inputRows = input.dimension(0);
    const int inputCols = input.dimension(1);
    const int outputRows = static_cast<int>(inputRows * scale);
    const int outputCols = static_cast<int>(inputCols * scale);
    
    // Define resizing operation with linear (bilinear) interpolation
    TensorResizingOp<InterpolateOp<LinearInterpolator<double>>, Tensor<double, 2>> resizer(
        input, InterpolateOp<LinearInterpolator<double>>(
            {outputRows, outputCols},  // Target dimensions
            {inputRows, inputCols}     // Original dimensions
        )
    );
    
    // Evaluate and return the scaled tensor
    return resizer.eval();
}

// Usage Example
int main() {
    // Create a 1000x1000 random tensor
    Tensor<double, 2> originalTensor(1000, 1000);
    originalTensor.setRandom();
    
    // Scale to 2000x2000
    Tensor<double, 2> scaledTensor = scaleTensor(originalTensor, 2.0);
    
    return 0;
}

Key Notes:

  • Interpolation Options: Replace LinearInterpolator with NearestInterpolator if you want nearest-neighbor scaling (faster but less smooth).
  • Build Requirements: Ensure your Eigen library is compiled with the Tensor module enabled (most pre-built packages include this by default, but double-check your build configuration).

内容的提问来源于stack exchange,提问作者Vicente Bosch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:05:17