OpenCV学习(58)

图像变换(12):重映射

一,重映射的概念;二,实现重映射:remapO函数;三,基础示例程序:基本重映射

一,重映射的概念

重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程,需要获得一些插值为非整数像素的坐标,因为源图像与目标图像的像素坐标不是一一对应的。一般情况下,我们通过重映射来表达每个像素的位置(x,y),像这样:

OpenCV学习(58)_第1张图片
图像会按照x轴方向发生翻转。那么,源图像和效果图分别如图7.27和7.28所示。

OpenCV学习(58)_第2张图片

二,实现重映射:remapO函数

remap()函数会根据指定的映射形式,将源图像进行重映射几何变换,基于的公式如下:

OpenCV学习(58)_第3张图片
 

       第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。
       第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果,需和源图片有一样的尺寸和类型。

       第三个参数,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插值方式在这里是不支持的,所以可选的插值方式如下(需要注意,这些宏相应的OpenCV2版为在它们的宏名称前面加上“CV_”前缀,比如“INTER_LINEAR”的OpenCV2版为“CV_INTER_LINEAR"):
                        INTER_NEAREST——最近邻插值
                        INTER_LINEAR——双线性插值(默认值)
                        INTER_CUBIC——双三次样条插值(逾4x4像素邻域内的双三次插值)

                        INTER_LANCZOS4———Lanczos插值(逾8×8像素邻域的Lanczos插值)

        第六个参数,int类型的borderMode,边界模式,有默认值 BORDERCONSTANT,表示目标图像中“离群点( outliers)”的像素值不会被此函数修改。
        第七个参数,const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar(),即默认值为0。
三,基础示例程序:基本重映射

代码如下:

//-------------【头文件、命名空间部分】--------------
//	描述:包含程序所依赖的头文件和命名空间
//---------------------------------------------------
#include 
#include 
#include 
#include 
using namespace std;
using namespace cv;

int main()
{
	cv::utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);//控制台不在输出日志文件
	//【0】变量定义
	Mat srcImage, dstImage;
	Mat map_x, map_y;

	//【1】载入原始图
	srcImage = imread("E:/pictures/2.jpg");
	if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false; }
	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(j, i) = static_cast(i);
			map_y.at(j, i) = static_cast(srcImage.rows - j);
		}
	}

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

	//【5】显示效果图
	imshow("【程序窗口】", dstImage);
	waitKey();

	return 0;
}

运行结果:
OpenCV学习(58)_第4张图片

 

 OpenCV学习(58)_第5张图片

 

你可能感兴趣的:(opencv,学习,人工智能)