图像重映射 - sumpig/OpenCV GitHub Wiki

本节来看看如何通过移动像素修改图像的外观。这个过程不会修改像素值,而是把每个像素的位置重新映射到新的位置。


实现

这里定义一个转换函数,在图像上创建波浪形效果:

// 重映射图像,创建波浪形效果
void wave(const cv::Mat &image, cv::Mat &result) {

    // 映射参数
    cv::Mat srcX(image.rows, image.cols, CV_32F);
    cv::Mat srcY(image.rows, image.cols, CV_32F);

    // 创建映射参数
    for (int i=0; i<image.rows; i++) {

        for (int j=0; j<image.cols; j++) {

            // (i,j)像素的新位置
            srcX.at<float>(i,j )= j; // 保持在同一列

            // 原来在第i 行的像素,现在根据一个正弦曲线移动
            srcY.at<float>(i,j) = i+5*sin(j/10.0);
        }
    }

    // 应用映射参数
    cv::remap(image, // 源图像
              result, // 目标图像
              srcX, // x 映射
              srcY, // y 映射
              cv::INTER_LINEAR); // 填补方法
}

原理

重映射是通过修改像素的位置,生成一个新版本的图像。为了构建新图像,需要知道目标图像中每个像素的原始位置。因此,我们需要的映射函数应该能根据像素的新位置得到像素的原始位置。这个转换过程描述了如何把新图像的像素映射回原始图像,因此称为反向映射。

在OpenCV中,可以用两个映射参数来说明反向映射:一个针对 x 坐标,另一个针对 y 坐标。它们都用浮点数型的 cv::Mat 实例来表示:

// 映射参数
cv::Mat srcX(image.rows, image.cols, CV_32F); // x 方向
cv::Mat srcY(image.rows, image.cols, CV_32F); // y 方向

图像翻转效果也可以用下面的映射参数创建:

// 创建映射参数
for (int i=0; i<image.rows; i++) {

    for (int j=0; j<image.cols; j++) {
    
        // 水平翻转
        srcX.at<float>(i,j)= image.cols-j-1;
        srcY.at<float>(i,j)= i;
    }
}
⚠️ **GitHub.com Fallback** ⚠️