OpenCV学习20--像素重映射

重映射就是把一个图像中一个为之的像素放置到另一个图片指定位置过程。为了完成重映射过程有必要获得一些插值作为非整数像素坐标,因为原图像与目标图像的像素坐标不是一一对应的。我们通过重映射来表达每个像素的位置(x, y):

g(x, y)=f(h(x,y))

这里g()是目标图像,f()是原图像,h(x,y)是作用于(x,y)的映射方法函数。假设有一幅图像I,满足下面条件作重映射:

h(x,y)=(I.cols - x,y)

图像会按照x轴方向发生反转,如下:

image.png

看到红色圈关于x的位置改变(x轴水平翻转)

image.png

opencv提供函数reman()实现简单的重映射。remap函数原型如下:

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

参数解释

. src:输入图像

. dst:目标图像,与原图像类型相同,与map1图像尺寸大小相等

. map1: (x, y)的第一个映射或者是CV_16SC2、CV_32FC1或CV_32FC2的x值。查询convertMaps获得详细解释。

. map2: 第二个map,表示类型为CV_16UC1、CV_32FC1的y值或空值(如果map1是用(x,y)进行表示)

. interpolation: 插值方式,在此函数中不支持INTER_AREA插值方法。插值方法如下(可通过InterpolationFlags查看)

image.png

. borderMode: 边界模式,有默认值BORDER_CONSTANT,表示目标图像中“离群点”的像素值不会被此函数修改
. borderValue: 当有常数边界时使用的值,有默认值Scalar()即0

示例代码

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

//定义全局变量
Mat srcImage, dstImage;
Mat map1_x, map2_y;
String windowName = "图像重映射";
int ind;        //重映射类型选择

void updateMap(void);

int main()
{
    //初始化参数
    ind = 0;
    srcImage = imread("dog.jpg");
    dstImage.create(srcImage.size(), srcImage.type());
    map1_x.create(srcImage.size(), CV_32FC1);
    map2_y.create(srcImage.size(), CV_32FC1);

    //创建窗口
    namedWindow(windowName, WINDOW_AUTOSIZE);

    while(true)
    {
        int c = waitKey(1000);      //延迟1000ms

        if((char)c == 27)
        {
            break;      //ESC退出
        }

        updateMap();        //调用函数,更新重映射模式
        remap(srcImage, dstImage, map1_x, map2_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));

        imshow(windowName, dstImage);
    }

    return 0;
}

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

    for(int j = 0; j < srcImage.rows; j++)
    {
        for(int i = 0; i < srcImage.cols; i++)
        {
            switch(ind)
            {
            //图像长宽缩小到原来的一半并居中显示
            case 0:
                if(i > srcImage.cols*0.25 && i < srcImage.cols*0.75 && j > srcImage.rows*0.25 && j < srcImage.rows*0.75)
                {
                    map1_x.at<float>(j, i) = 2*(i - srcImage.cols*0.25) + 0.5;
                    map2_y.at<float>(j, i) = 2*(j - srcImage.rows*0.25) + 0.5;
                }
                else
                {
                    map1_x.at<float>(j, i) = 0;
                    map2_y.at<float>(j, i) = 0;
                }
                break;

            //图像左右翻转
            case 1:
                map1_x.at<float>(j, i) = i;
                map2_y.at<float>(j, i) = srcImage.rows - j;
                break;

            //图像上下翻转
            case 2:
                map1_x.at<float>(j, i) = srcImage.cols - i;
                map2_y.at<float>(j, i) = j;
                break;

            //图像上下左右均翻转
            case 3:
                map1_x.at<float>(j, i) = srcImage.cols - i;
                map2_y.at<float>(j, i) = srcImage.rows - j;
                break;

            default:
                break;
            }
        }
    }

    ind++;
}

————————————————


运行结果
图像缩小

image.png

左右翻转

image.png

上下翻转

image.png




版权声明:本文为CSDN博主「梧桐栖鸦」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:

https://blog.csdn.net/keith_bb/article/details/56295873


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864