【OpenCV】重映射及仿射变换

重映射Remapping

void cv::remap  (   InputArray  src,  OutputArray   dst,
                    InputArray  map1, InputArray    map2,
                    int     interpolation, int  borderMode = BORDER_CONSTANT,
                    const Scalar &  borderValue = Scalar() 
)   

说明
    src: 源图像
    dst: 目标图像,与 src 相同大小
    map_x: x方向的映射参数. 它相当于方法 h(i,j) 的第一个参数
    map_y: y方向的映射参数. 注意 map_y 和 map_x 与 src 的大小一致。
    CV_INTER_LINEAR: 非整数像素坐标插值标志. 这里给出的是默认值(双线性插值)。
    BORDER_CONSTANT: 默认


代码示例

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

Mat src, dst;
Mat map_x, map_y;
char* remap_window = "Remap Demo";
int ind = 0;

void update_map(void);

int main(int argc, char** argv)
{
    CommandLineParser parser(argc, argv, "{@image | ../data/lena.jpg | input image}");
    string filename = parser.get<string>(0);
    src = imread(filename, IMREAD_COLOR);

    dst.create(src.size(), src.type());
    map_x.create(src.size(), CV_32FC1);         // 32位浮点型单通道矩阵
    map_y.create(src.size(), CV_32FC1);

    while (true)
    {
        char c = (char)waitKey(1000);
        if (c == 27) { break; }

        update_map();
        remap(src, dst, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));  // 重映射

        imshow(remap_window, dst);
    }
    return 0;
}

void update_map(void)
{
    ind = ind % 4;

    for(int j =0;j<src.rows;j++)
        for (int i = 0; i < src.cols; i++)
        {
            switch (ind)
            {
                case 0:    // 图像宽高缩小一半,并显示在中间
                    if (i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75)
                    {
                        map_x.at<float>(j, i) = 2 * (i - src.cols*0.25f) + 0.5f;
                        map_y.at<float>(j, i) = 2 * (j - src.rows*0.25f) + 0.5f;
                    }
                    else
                    {
                        map_x.at<float>(j, i) = 0;
                        map_y.at<float>(j, i) = 0;
                    }
                    break;
                case 1:    // 图像上下颠倒
                    map_x.at<float>(j, i) = (float)i;
                    map_y.at<float>(j, i) = (float)(src.rows - j);
                    break;
                case 2:    // 图像左右颠倒
                    map_x.at<float>(j, i) = (float)(src.cols - i);
                    map_y.at<float>(j, i) = (float)j;
                    break;
                case 3:    // 同时执行b和c的操作
                    map_x.at<float>(j, i) = (float)(src.cols - i);
                    map_y.at<float>(j, i) = (float)(src.rows - j);
                    break;
            }
        }
    ind++;
}


运行结果



仿射变换Affine Transformations

void cv::warpAffine (   InputArray  src,  OutputArray   dst,
                        InputArray  M,    Size  dsize,
                        int flags = INTER_LINEAR,int    borderMode = BORDER_CONSTANT,
                        const Scalar &  borderValue = Scalar() 
)

说明
    src: 输入源图像
    dst: 输出图像
    M  : 仿射变换矩阵
    dsize: 输出图像的尺寸


代码示例

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

char* source_window = "Source image";
char* warp_window = "Warp";
char* warp_rotate_window = "Warp + Rotate";

int main(int, char** argv)
{
    Point2f srcTri[3];          // 三角形三个顶点
    Point2f dstTri[3];

    Mat rot_mat(2, 3, CV_32FC1);
    Mat warp_mat(2, 3, CV_32FC1);
    Mat src, warp_dst, warp_rotate_dst;

    char* filename = "../data/lena.jpg";
    src = imread(filename, IMREAD_COLOR);

    warp_dst = Mat::zeros(src.rows, src.cols, src.type());

    srcTri[0] = Point2f(0, 0);                              // 图像左上角
    srcTri[1] = Point2f(src.cols - 1.f, 0);                 // 图像右上角
    srcTri[2] = Point2f(0, src.rows - 1.f);                 // 图像左下角

    dstTri[0] = Point2f(src.cols*0.0f, src.rows*0.33f);
    dstTri[1] = Point2f(src.cols*0.85f, src.rows*0.25f);
    dstTri[2] = Point2f(src.cols*0.15f, src.rows*0.7f);

    warp_mat = getAffineTransform(srcTri, dstTri);          // 得到仿射矩阵
    warpAffine(src, warp_dst, warp_mat, warp_dst.size());   // 仿射变换

    Point center = Point(warp_dst.cols / 2, warp_dst.rows / 2);
    double angle = -50.0;
    double scale = 0.6;

    rot_mat = getRotationMatrix2D(center, angle, scale);

    warpAffine(warp_dst, warp_rotate_dst, rot_mat, warp_dst.size());    // 旋转仿射变换

    imshow(source_window, src);
    imshow(warp_window, warp_dst);
    imshow(warp_rotate_window, warp_rotate_dst);

    waitKey(0);
    return 0;
}


运行结果




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值