首页 > 其他分享 >【OpenCV】-重映射

【OpenCV】-重映射

时间:2023-02-15 11:38:40浏览次数:64  
标签:map 映射 srcImage int OpenCV static CV


文章目录

  • ​​1、重映射的概念​​
  • ​​2、实现重映射:remap()函数​​
  • ​​3、基本重映射​​
  • ​​4、实现多重映射​​

1、重映射的概念

重映射是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成重映射过程,需要获得一些插值为非整数像素的坐标,因为源图像与目标图像像素坐标不是一一对应的。如下:
【OpenCV】-重映射_opencv
g()是目标图像,f()是源图像,而h(x,y)是作用于(x,y)的映射方法函数。

2、实现重映射:remap()函数

remap()函数会根据指定的映射形式,将源图像进行重映射几何变换:
【OpenCV】-重映射_图像处理_02

void remap(InputArray src,OutputArray dst,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表示点(x,y)时,这个参数不代表任何值
  • 表示CV_16UC1,CV_32FC1类型的Y值
  • 第五个参数:int 类型的interpolation,插值方式,所选的插值方式如下:
  • INTER_NEAREST——最近邻插值
  • INTER_LINEAR——双线性插值(默认值)
  • INTER_CUBIC——双三次样条插值
  • INTER_LANCZOS4——Lanczos插值
  • 第六个参数:边界模式
  • 第七个参数:const Scalar&类型的borderValue,当有常数边界使用的值,其默认值Scalar(),即默认值为0

3、基本重映射

说明:下面是精简后的以remap函数为核心的示例程序

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage, dstImage;
Mat map_x, map_y;
//载入原始图像
srcImage = imread("E:\\Pec\\car.jpg", 1);
imshow("【原始图】", srcImage);
//创建和原始图一样的效果图,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++)
{
//通过at获取像素值
map_x.at<float>(j, i) = static_cast<float>(i);
map_y.at<float>(j, i) = static_cast<float>(srcImage.rows-j);
}
}
//进行重映射
remap(srcImage, dstImage, map_x, map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow("【效果图】", dstImage);

waitKey(0);
}

【OpenCV】-重映射_#include_03

4、实现多重映射

#include<opencv2/opencv.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
#define WINDOW_NAME "【程序窗口】"
Mat g_srcImage, g_dstImage;
Mat g_map_x, g_map_y;
int update_map(int key);
static void ShowHelpText();
int main()
{
system("color 2F");
ShowHelpText();
//载入原始图像
g_srcImage = imread("E:\\Pec\\car.jpg", 1);
imshow("【原始图】", 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, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME, g_srcImage);
while (1)
{
int key = waitKey(0);
if ((key & 255) == 27)
{
cout << "程序退出......" << endl;
break;
}
update_map(key);
//根据按下键盘按键来更新map_x & map_y的值,然后调用remap()进行重映射
remap(g_srcImage, g_dstImage, g_map_x, g_map_y, INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
imshow(WINDOW_NAME, g_dstImage);
}
return 0;
}
int update_map(int key)
{
//双层循环,遍历每一个像素点,改变map_x和Map_y
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) = 2 * (i - g_srcImage.cols*0.25) + 0.5;
g_map_y.at<float>(j, i) = 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按下,进行第二重映射操作
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':
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':
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;
}
static void ShowHelpText()
{
cout << "\n\n\n\t欢迎来到重映射示例程序\n";
cout << "\n\n\n\t按键操作如下:" ;
cout << "\n\n\n\t键盘按下【ESC】-退出程序" ;
cout << "\n\n\n\t键盘按下【1】-第一种映射方式,缩小2倍" ;
cout << "\n\n\n\t键盘按下【2】-第二种映射方式,y方向翻转" ;
cout << "\n\n\n\t键盘按下【3】-第三种映射方式,x方向反转" ;
cout << "\n\n\n\t键盘按下【4】-第四种映射方式,x,y方向反转" ;
}

第一种映射方式,缩小2倍

【OpenCV】-重映射_图像处理_04

第二种映射方式,y方向翻转

【OpenCV】-重映射_计算机视觉_05

第三种映射方式,x方向反转

【OpenCV】-重映射_图像处理_06

第四种映射方式,x,y方向反转

【OpenCV】-重映射_图像处理_07


标签:map,映射,srcImage,int,OpenCV,static,CV
From: https://blog.51cto.com/u_14935708/6058963

相关文章

  • 【OpenCV】-霍夫变换
    序言:什么是霍夫变换?在图像处理和计算机视觉邻域中,如何从当前的图像中提前所需要的特征信息是图像识别的关键所在。霍夫变换可以快速准确地检测出直线或者圆,在图像处理中识别......
  • 【OpenCV】-边缘检测汇总示例
    汇总之前:这一节还有一个scharr滤波器(也是算子)没有介绍,先介绍一下。。。1计算图像差分:Scharr()函数使用Scharr滤波器运算符计算x或y方向的图像差分,包含的参数与Sobel算子基......
  • 【OpenCV】-算子(Sobel、Canny、Laplacian)学习
    开头一下:本篇博客主要介绍边缘检测所涉及的三大算子,分别是Sobel算子、Canny算子、Laplacian算子)。上篇博客​​python版CV​​也介绍了这三个算子的用法。文章目录​​1、s......
  • pycharm配置opencv库
    我走的弯路:对于刚刚入手OpenCV的小白,又第一次接触pycharm编译器。所以在配置opencv库的时候遇到很多问题。如下:1、如果直接在Terminal运行界面输入【pipinstallopencv-p......
  • 【OpenCV】—阈值化
    什么是阈值化?答:在对各种图形进行处理操作的过程中,需要对图像中的像素做出取舍与决策,直接剔除一些低于或者高于一定值的像素。阈值可以被视作最简单的图像分割方法。如:从一......
  • 【OpenCV】图片尺寸放缩示例程序
    这次示例程序分别演示了用resize、pyrUp、pyrDown来让源图像进行放大缩小操作#include<opencv2/opencv.hpp>#include<opencv2/imgproc/imgproc.hpp>#include<opencv2/highgu......
  • 【OpenCV】—图像金子塔与图片尺寸缩放
    序言:继续,继续,开干!!!本节学习OpenCV中的函数pyrUp和pyrDown对图像进行向上和向下采样,以及了解专门用于缩放图像尺寸的resize函数的用法文章目录​​1、引言​​​​2、关于图......
  • 【OpenCV】—线性滤波:方框滤波、均值滤波、高斯滤波
    文章目录​​一、线性滤波:方框滤波、均值滤波、高斯滤波​​​​1、平滑处理​​​​2、图像滤波与滤波器​​​​3、线性滤波器的简介​​​​4、滤波和模糊​​​​5、邻......
  • 在OpenCV图片(cv::Mat格式)输出汉字
    staticvoidputTextZH(constcv::Mat&inMat,constQStringtext,constcv::PointwordCenter,intinWordSize,constcv::ScalarinColor){QImageimage;swit......
  • QT+opencv显示图片
    借鉴该文章https://blog.csdn.net/m0_60259116/article/details/128104565 opencv的Mingw版本放在E盘所以在工程文件中添加如下地址:INCLUDEPATH+=E:\opencv3.4.0\Op......