opencv remap函数测试 remap()简单重映射

重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。
为了完成映射过程, 我们需要获得一些插值为非整数像素的坐标,因为源图像与目标图像的像素坐标不是一一对应的。
一般情况下,我们通过重映射来表达每个像素的位置 (x,y),
像这样 : g(x,y) = f ( h(x,y) )
在这里, g( ) 是目标图像, f() 是源图像, 而h(x,y) 是作用于 (x,y) 的映射方法函数。
在OpenCV中,我们用函数remap( )来实现简单重映射。
1047308-20191223202652892-327856936.png

C++: 
void remap(InputArray src, //输入图像
           OutputArraydst, //输出图像
           InputArray map1,//第一个映射
           InputArray map2, //第二个映射
           int interpolation, //插值
           intborderMode=BORDER_CONSTANT, 
           const Scalar& borderValue=Scalar()
           )
第三个参数,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。

.pro文件

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp

OPENCV_ROOT_PATH = /home/yhl/software_install/opencv3.2



INCLUDEPATH += $${OPENCV_ROOT_PATH}/include \
               $${OPENCV_ROOT_PATH}/include/opencv \
               $${OPENCV_ROOT_PATH}/include/opencv2

LIBS += -L$${OPENCV_ROOT_PATH}/lib

LIBS += -lopencv_core \
        -lopencv_highgui \
        -lopencv_imgproc \
        -lopencv_imgcodecs \
        -lopencv_videoio \
        -lopencv_calib3d
//-----------------------------------【头文件包含部分】---------------------------------------
//       描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
#include <iostream>

//-----------------------------------【命名空间声明部分】--------------------------------------
//    描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;

//-----------------------------------【main( )函数】--------------------------------------------
//    描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( )
{
    //【0】变量定义
    Mat srcImage, dstImage;
    Mat map_x, map_y;

    //【1】载入原始图
    srcImage= imread( "/data_2/everyday/1223/dog.jpeg", 1 );
    if(!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
    namedWindow("原始图",0);
    imshow("原始图",srcImage);

    //【2】创建和原始图一样的效果图,x重映射图,y重映射图
    dstImage.create(srcImage.size(), srcImage.type() );
    map_x.create(srcImage.size(), CV_32FC1 );
    map_y.create(srcImage.size(), CV_32FC1 );

    //【3】双层循环,遍历每一个像素点,改变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>(srcImage.cols - i);
            map_y.at<float>(j,i)= static_cast<float>(j);
        }
    }

    //【4】进行重映射操作
    remap(srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0,0,0) );

    //【5】显示效果图
    namedWindow("remap",0);
    imshow("remap", dstImage );
    waitKey();

    return 0;
}

测试图片如下,治愈系的小奶狗,^_^
1047308-20191223202933383-755482852.png

OpenCV中的remap函数可以实现图像重映射操作。它可以用于实现各种图像处理操作,例如图像缩放、旋转、镜像等。具体来说,remap函数可以将输入图像中的每个像素映射到输出图像中的新位置。 remap函数的原型如下: ```c++ void cv::remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode, const Scalar& borderValue) ``` 参数说明: - src:输入图像。 - dst:输出图像。 - map1:第一个映射矩阵,可以是浮点型的二维数组或者单通道的浮点型图像。 - map2:第二个映射矩阵,可以是浮点型的二维数组或者单通道的浮点型图像。 - interpolation:插值方法,可以取以下值之一:INTER_NEAREST、INTER_LINEAR、INTER_CUBIC、INTER_AREA、INTER_LANCZOS4。 - borderMode:边界模式,可以取以下值之一:BORDER_CONSTANT、BORDER_REPLICATE、BORDER_REFLECT、BORDER_WRAP、BORDER_REFLECT_101。 - borderValue:边界值,当borderMode为BORDER_CONSTANT时,用于填充边界的像素值。 具体来说,remap函数将输入图像中的每个像素(x,y)通过map1(x,y)和map2(x,y)映射到输出图像中的位置(x',y'),然后使用指定的插值方法计算输出图像中位置(x',y')处的像素值。如果映射矩阵的尺寸与输入图像的尺寸不匹配,则只处理匹配部分。 下面是一个简单的例子,演示如何使用remap函数实现图像的水平镜像: ```c++ cv::Mat input_image = cv::imread("input_image.jpg"); cv::Mat map_x(input_image.size(), CV_32FC1); cv::Mat map_y(input_image.size(), CV_32FC1); for (int i = 0; i < input_image.rows; i++) { for (int j = 0; j < input_image.cols; j++) { map_x.at<float>(i, j) = input_image.cols - j - 1; map_y.at<float>(i, j) = i; } } cv::Mat output_image; cv::remap(input_image, output_image, map_x, map_y, cv::INTER_LINEAR); cv::imshow("Input Image", input_image); cv::imshow("Output Image", output_image); cv::waitKey(0); ``` 上述代码中,我们首先创建两个映射矩阵map_x和map_y,用于实现水平镜像。然后,我们将输入图像和映射矩阵作为参数调用remap函数,得到输出图像output_image。最后,我们使用imshow函数显示输入图像和输出图像
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值