opencv重映射remap( )函数

本文介绍了一个使用C++实现的图像重映射示例代码,详细展示了如何通过改变像素坐标值来达到图像翻转等效果。该示例包括了创建窗口、读取图像、创建重映射图并应用重映射操作的过程。


int main(int argc, char** argv)
{
 Mat srcImage, dstImage;
 Mat map_x, map_y;
 namedWindow("程序窗口");
 //载入原始图 
 srcImage = imread("test.jpg", 1);
 //创建和原始图一样的效果图,x重映射图,y重映射图
 dstImage.create(srcImage.size(), srcImage.type());
 map_x.create(srcImage.size(), CV_32FC1);
 map_y.create(srcImage.size(), CV_32FC1);
 //双层循环,遍历每一个像素点,改变map_x & map_y的值 
 for (int j = 0; j < srcImage.rows; j++)
   {
       for (int i = 0; i < srcImage.cols; i++)
         {
           //改变map_x & map_y的值.  
        map_x.at<float>(j, i) = static_cast<float>(i);
           map_y.at<float>(j, i) = static_cast<float>(srcImage.rows - j);
     /////////////////////////////////////////////////////////
     //map_x.at<float>(j, i) = static_cast<float>(srcImage.cols-i);
     // map_y.at<float>(j, i) = static_cast<float>(j);
     ///////////////////////////////////////////////////////
     //map_x.at<float>(j, i) = static_cast<float>(srcImage.cols-i);
     //map_y.at<float>(j, i) = static_cast<float>(srcImage.rows - j);
     /////////////////////////////////////////////////////////
     //map_x.at<float>(j, i) = static_cast<float>(2*( i - srcImage.cols*0.25 ) + 0.5);
     //map_y.at<float>(j, i) = static_cast<float>(2*( j - srcImage.rows*0.25 ) + 0.5);
          }
     }
 //进行重映射操作
 remap(srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
 imshow("程序窗口", dstImage);
 waitKey(30);
 return(0);
}

C++: void remap(InputArray src, OutputArraydst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。

  • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果,需和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray类型的map1,它有两种可能的表示对象。
          • 表示点(x,y)的第一个映射。
          • 表示CV_16SC2 , CV_32FC1 或CV_32FC2类型的X值。
      • 第四个参数,InputArray类型的map2,同样,它也有两种可能的表示对象,而且他是根据map1来确定表示那种对象。
          • 若map1表示点(x,y)时。这个参数不代表任何值。
          • 表示CV_16UC1 , CV_32FC1类型的Y值(第二个值)。

    • 第五个参数,int类型的interpolation,插值方式,之前的resize( )函数中有讲到,需要注意,resize( )函数中提到的INTER_AREA插值方式在这里是不支持的,所以可选的插值方式如下:
        • INTER_NEAREST - 最近邻插值
        • INTER_LINEAR – 双线性插值(默认值)
        • INTER_CUBIC – 双三次样条插值(逾4×4像素邻域内的双三次插值)
        • INTER_LANCZOS4 -Lanczos插值(逾8×8像素邻域的Lanczos插值)

    • 第六个参数,int类型的borderMode,边界模式,有默认值BORDER_CONSTANT,表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。
    • 第七个参数,const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar( ),即默认值为0。


    
### 关于 `remap` 函数 #### OpenCV 中的 `remap` 函数介绍 OpenCV 提供了一个名为 `remap()` 的函数用于实现图像的重映射操作。该函数允许通过指定两个映射表来定义源图中每个像素的新位置,从而完成复杂的几何变换[^2]。 具体来说,在调用此 API 后,程序会依据给定的地图文件(mapx 和 mapy),按照公式 \(dst(x,y)=src(mapx(x,y),mapy(x,y))\) 来重新排列原始图片上的每一个点的位置,并最终形成一张新的目标图片[^4]。 当执行这种类型的转换时,由于新旧坐标之间可能存在不完全匹配的情况,所以通常还需要采用某种形式的插值算法来估算那些不在整数坐标的像素颜色值;常用的有最近邻法(NN)、双线性(BILINEAR)以及三次样条(CUBIC)[^1]。 下面是具体的 C++ 实现例子: ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main(){ Mat image = imread("input.jpg"); // 加载输入图像 int width = image.cols; int height = image.rows; // 创建映射矩阵 Mat map_x(height, width, CV_32FC1); Mat map_y(height, width, CV_32FC1); for(int i=0; i<height; ++i){ for(int j=0; j<width; ++j){ float fx = static_cast<float>(j); float fy = static_cast<float>(i); // 这里可以自定义映射逻辑 map_x.at<float>(i,j) = fx * cos(PI / 4.f) - fy * sin(PI / 4.f); map_y.at<float>(i,j) = fx * sin(PI / 4.f) + fy * cos(PI / 4.f); } } Mat result; // 执行重映射操作 remap(image, result, map_x, map_y, INTER_LINEAR); imwrite("output.png",result); // 输出处理后的图像到磁盘上保存下来 } ``` 这段代码展示了如何创建一对浮点型单通道灰度级映射表格 (`map_x`, `map_y`) 并利用它们来进行一次简单的旋转效果模拟。注意这里只是简单地实现了顺时针方向45°角的旋转变换作为示范用途而已。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vqt5_qt6

你的鼓励是我们创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值