Opencv学习之重映射

来源:互联网 发布:史密斯热水器 贵 知乎 编辑:程序博客网 时间:2024/05/18 01:36

Opencv学习之重映射–remap函数

重映射,就是把一幅图像中某个位置的像素放置到另一个图片指定位置的过程。为了完成映射过程,需要获得一些插值为非整数像素的坐标,因为源图像与目标图的像素坐标不是一一对应的。
void remap(inputArray,outputArray,map1,map2,int interpolation,int borderMode=BORDER_CONSTANT,const Scalar& borderValue=Scalar())
*第一个参数,输入图像,单通道8位或者浮点型图像。
*第二个参数,这个参数用于存放函数调用后的输出结果,需和源图片有一样的尺寸和类型。
*第三个参数,(1)表示点(x,y)的第一个映射
(2)表示CV_16SC2、32FC1或32FC2类型的X值
*第四个参数,会根据map1来确定表示那种对象
(1)若map1表示点(x,y)时,这个参数不代表任何值。
(2)表示CV_16UC1、32FC1类型的Y值(第二个值)
*第五个参数,插值方式:
(1)CV_INTER_NEAREST–最近邻插值
(2)CV_INTER_LINEAR–双线性插值(默认值)
(3)CV_INTER_CUBIC–双三次样条插值(4x4像素邻域内的双三次插值)
(4)CV_INTER-LANCZOS4–Lanczos插值(8x8像素邻域的Lanczos插值)
*第六个参数,边界模式,默认值表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。
*第七个参数,默认值为0。

#include<opencv2/highgui/highgui.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<iostream>using namespace cv;using namespace std;//宏定义部分#define WINDOW_NAME "[Procedure Window]"//全局变量声明Mat g_srcImage,g_dstImage;Mat g_map_x,g_map_y;//全局函数声明int update_map(int key);//主函数int main(){   //载入源图像    g_srcImage=imread("/Users/new/Desktop/3.jpg");    if(!g_srcImage.data){printf("读取源图像srcImage错误~!\n");return false;}    //显示源图像    imshow("image[origin]",g_srcImage);    //创建和源图像一样的目标图,x重映射图,y重映射图    g_dstImage.create(g_srcImage.size(),g_srcImage.type());    g_map_x.create(g_srcImage.size(), CV_32FC1);    g_map_y.create(g_srcImage.size(), CV_32FC1);    //创建窗口并显示    namedWindow(WINDOW_NAME);    imshow(WINDOW_NAME,g_srcImage);    //轮训按键,更新map_x和map_y的值,进行重映射操作并显示目标图    while(1)    {        int key=waitKey(0);        //判断ESC是否按下,若按下便退出        if((key & 255)==27)        {            cout<<"程序退出...\n";            break;        }        //根据按下的键盘按键来更新map_x和map_y的值,然后调用remap进行重映射。        update_map(key);        remap(g_srcImage, g_dstImage, g_map_x, g_map_y, INTER_LINEAR);              imshow(WINDOW_NAME,g_dstImage);    }              return 0;}//update_map函数定义int update_map(int key){    //双层循环,遍历每一个像素点    for(int j=0;j<g_srcImage.rows;++j)    {        for(int i=0;i<g_srcImage.cols;++i)        {            switch(key)            {                    case '1'://按下1,进行第一种重映射操作:缩小两倍                        if(i>g_srcImage.cols*0.25 && i<g_srcImage.cols*0.75 && j>g_srcImage.rows*0.25 && j<g_srcImage.rows*0.75)                        {                            g_map_x.at<float>(j,i)=static_cast<float>(2*(i-g_srcImage.cols*0.25)+0.5);                            g_map_y.at<float>(j,i)=static_cast<float>(2*(j-g_srcImage.rows*0.25)+0.5);                        }                        else                        {                            g_map_x.at<float>(j,i)=0;                            g_map_y.at<float>(j,i)=0;                        }                        break;                    case '2'://按下2,进行第二种重映射操作:y方向上的翻转                        g_map_x.at<float>(j,i)=static_cast<float>(i);                        g_map_y.at<float>(j,i)=static_cast<float>(g_srcImage.rows-j);                        break;                    case '3'://按下3,进行第三种重映射操作:x方向上的翻转                        g_map_x.at<float>(j,i)=static_cast<float>(g_srcImage.cols-i);                        g_map_y.at<float>(j,i)=static_cast<float>(j);                        break;                    case '4'://按下4,进行第四种重映射操作:x、y方向上都翻转                        g_map_x.at<float>(j,i)=static_cast<float>(g_srcImage.cols-i);                        g_map_y.at<float>(j,i)=static_cast<float>(g_srcImage.rows-j);                        break;            }        }    }    return 1;}

缩小两倍:
这里写图片描述

垂直翻转:
这里写图片描述

水平翻转:
这里写图片描述

对称翻转:
这里写图片描述

Opencv技巧

(1)创建重映射图时:g_map_x.create(g_srcImage.size(),CV_32FC1),这里的type不是g_srcImage.size()而是CV_32FC1,切记!
(2)对重映射图的像素进行操作有如:g_map_x.at(j,i)=static_cast(g_srcImage.cols-i);

阅读全文
0 0