如何对Eigen矩阵的滑动窗口子矩阵应用自定义函数?
If you want to apply a sliding window operation to an Eigen matrix—where each output element depends on a local neighborhood (window) around the corresponding input element—here's a straightforward approach. Unlike unaryExpr which works on individual elements, we’ll need to iterate through each element, extract the relevant window, and apply your custom foo function to compute the result.
Example Implementation
Let’s walk through a complete example. We’ll create a function that takes an Eigen matrix and window size, then returns a new matrix where each element is the output of your foo function applied to the sliding window centered at that element. We’ll handle edge cases by clamping windows to the matrix bounds (you can adjust padding logic if needed).
First, define your foo function—this is where you’ll put the core logic to process the window. For this example, let’s make it compute the sum of all elements in the window:
#include <Eigen/Core> #include <iostream> #include <algorithm> // For std::max/min // Your custom sliding window processing function double foo(const Eigen::MatrixXd& window) { // Replace this with your own window processing logic! // Example: Calculate the sum of all elements in the window return window.sum(); // Other ideas: return window.mean();, return window.maxCoeff();, etc. } // Helper function to apply the sliding window to the input matrix Eigen::MatrixXd applySlidingWindow(const Eigen::MatrixXd& input, int windowSize) { // Enforce odd window size for centered windows (adjust if you need even sizes) if (windowSize % 2 == 0) { std::cerr << "Window size should be odd for centered sliding windows." << std::endl; return input; } int halfWindow = windowSize / 2; int rows = input.rows(); int cols = input.cols(); // Initialize output matrix with the same dimensions as input Eigen::MatrixXd output(rows, cols); // Iterate over each element in the input matrix for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { // Calculate window bounds, clamping to avoid out-of-bounds access int startRow = std::max(0, i - halfWindow); int endRow = std::min(rows - 1, i + halfWindow); int startCol = std::max(0, j - halfWindow); int endCol = std::min(cols - 1, j + halfWindow); // Extract the window from the input matrix Eigen::MatrixXd window = input.block(startRow, startCol, endRow - startRow + 1, endCol - startCol + 1); // Apply your custom foo function to the window output(i, j) = foo(window); } } return output; } int main() { // Test with a 3x3 matrix Eigen::MatrixXd m(3, 3); m << 1, 2, 3, 4, 5, 6, 7, 8, 9; std::cout << "Original matrix:\n" << m << "\n\n"; // Apply 3x3 sliding window Eigen::MatrixXd result = applySlidingWindow(m, 3); std::cout << "Sliding window sum result:\n" << result << "\n"; return 0; }
Key Customization Tips
- Modify
foo: Swap the sum logic infoowith whatever you need—mean, maximum value, convolution, or any custom calculation that uses the window’s elements. - Edge Handling: The example uses clamping (so border elements use smaller windows). If you prefer zero-padding for out-of-bounds areas, create a padded version of the input matrix first before extracting windows.
- Window Size: Adjust the window size check if you need even-sized windows—just update how you calculate the window bounds to fit your use case.
Example Output
When you run the code, you’ll see:
Original matrix: 1 2 3 4 5 6 7 8 9 Sliding window sum result: 12 21 18 24 45 30 21 36 24
The center element (1,1) in the result is 45, which is the sum of all 9 elements in the original matrix.
内容的提问来源于stack exchange,提问作者Ken Y-N

