OpenCV学习笔记基础篇(十四):重映射、仿射变换、直方图均衡化

本文介绍了OpenCV中的图像处理技术,包括重映射(remap)用于像素位置变换,仿射变换(warpAffine)用于图像旋转和平移,以及直方图均衡化(equalizeHist)以增强图像对比度。作者通过代码示例详细解释了这些函数的使用方法和参数含义。
摘要由CSDN通过智能技术生成

前言:

笔者目前在校本科大二,有志于进行计算机视觉、计算机图形学方向的研究,准备系统性地、扎实的学习一遍OpenCV的内容,故记录学习笔记,同时,由于笔者同时学习数据结构、机器学习等知识,会尽量根据自己的理解,指出OpenCV的应用,并在加上自己理解的前提下进行叙述。
若有不当之处,希望各位批评、指正。


本篇学习内容:

1.重映射
2.仿射变换
3.直方图均衡化


1.重映射

摘自《OpenCV3编程入门》:
重映射,就是把一幅图像中某位置的像素放置到另一个图片指定位置的过程。为了完成映射过程,需要获得一些插值为非整数像素的坐标,因为源图像与目标图像的像素坐标不是一一对应的。

用remap()进行重映射:

void cv::remap	(	
InputArray 	src,		//输入图像
OutputArray dst,		//输出图像
InputArray 	map1,		
InputArray 	map2,
int 	interpolation,	//插值方式
int 	borderMode = BORDER_CONSTANT,	//边界模式
const Scalar & 	borderValue = Scalar() 	//边界值
)	

remap()的公式如下:
在这里插入图片描述

对部分参数进行进一步介绍:
map1,map2: 有两种方式来输入这两个参数。
第一种方式是让map1表示src的x坐标的映射后的指定位置,map2表示src的y坐标的映射后的指定位置。
第二种方式是让map1表示src的(x,y)坐标的映射后的指定位置,这种情况下,map2可以输入一个空Mat类。

下面用一个例子来展示这两种方式:

Mat img = imread("E:/program/image/1.jpg");
//方式一
Mat map_x, map_y, dst;
dst.create(img.size(), img.type());
map_x.create(img.size(), CV_32F);
map_y.create(img.size(), CV_32F);
for (int i = 0; i < img.rows; i++) {
	for (int j = 0; j < img.cols; j++) {
		map_x.at<float>(i, j) = img.cols - j;
		map_y.at<float>(i, j) = i;
	}
}
//方式二
Mat map_xy, y, dst2;
map_xy.create(img.size(), CV_32FC2);
dst2.create(img.size(), img.type());
for (int i = 0; i < img.rows; i++) {
	for (int j = 0; j < img.cols; j++) {
		map_xy.at<Vec2f>(i, j)[0] = img.cols - j;
		map_xy.at<Vec2f>(i, j)[1] = i;
	}
}

remap(img, dst, map_x, map_y, INTER_NEAREST);
remap(img, dst2, map_xy, y, INTER_NEAREST);

imshow("img", img);
imshow("dst", dst);
imshow("dst2", dst2);
waitKey();

在这里插入图片描述

2.仿射变换

相信在高中数学中,大家就对仿射变换不陌生。线性代数中用矩阵变换的角度来进一步进行仿射变换的定义。在线性代数中,仿射变换可以理解为一个向量空间到另一个向量空间的映射(以矩阵相乘的形式),而保持一些性质不变。在对二维图像的处理中,我们可以把它再简化一下,即:对(x,y)左乘一个2×2的矩阵,再在右边加上一个2×1的常数(a,b)。这个2×2的矩阵和1×2的常数合起来是一个2×3的矩阵,这通常被称之为仿射变换矩阵M。
公式如下:(这即是warpAffine()的公式)
在这里插入图片描述
用warpAffine()进行仿射变换:

void cv::warpAffine	(	
InputArray 	src,		//输入图像
OutputArray dst,		//输出图像
InputArray 	M,			//放射变换矩阵
Size 	dsize,			//输出图像的大小 size
int 	flags = INTER_LINEAR,			//标识符,插值方法和逆变换选项
int 	borderMode = BORDER_CONSTANT,	//边界模式
const Scalar & 	borderValue = Scalar() 	//边界值
)	

对部分参数进行进一步介绍:
flags: 这是插值方式和逆变换选项的组合标识符。比如说,可以设置一个插值方式,再设置WARP_INVERSE_MAP表明M是一个逆变换。
在这里插入图片描述
用getRotationMatrix2D()进行计算二维旋转变换矩阵:

Mat cv::getRotationMatrix2D	(	
Point2f center,	//旋转中心
double 	angle,	//旋转角度
double 	scale 	//缩放系数
)	

注意:getRotationMatrix2D()只是用于获取一个旋转矩阵,这个矩阵是要输入到warpAffine()里面的。
在这里插入图片描述
用getAffineTransform()计算仿射变换矩阵:

Mat cv::getAffineTransform	(	
const Point2f 	src[],
const Point2f 	dst[] 
)	

输入的src[]和dst[]是2个三角形的顶点。

下面用一个例子来展示这三个函数:

Mat img = imread("E:/program/image/1.jpg");
Mat dst;
Mat M;
Point2f srcp[3];
Point2f dstp[3];
srcp[0] = Point2f(0, 0);
srcp[1] = Point2f(100, 100);
srcp[2] = Point2f(100, 0);
dstp[0] = Point2f(10, 10);
dstp[1] = Point2f(50, 80);
dstp[2] = Point2f(10, 50);
M = getAffineTransform(srcp, dstp);
Mat rotate;
rotate = getRotationMatrix2D(Point(100, 100), 30.0, 1.2);
warpAffine(img, dst, M, img.size());
warpAffine(dst, dst, rotate, img.size());
imshow("img", img);
imshow("dst", dst);
waitKey();

在这里插入图片描述

3.直方图均衡化

直方图均衡化就是用一定的算法使直方图大致平和的方法。
再具体一些,直方图均衡化就是通过拉伸像素强度分布范围来增强对比度的一种方法。
用equalizeHist()来进行直方图均衡化:

void cv::equalizeHist	(	
InputArray 	src,
OutputArray dst 
)	

注意:输入图像只能是8位单通道图像。

一个小例子:

Mat img = imread("E:/program/image/1.jpg");
Mat src;
cvtColor(img, src, COLOR_BGR2GRAY);
Mat dst;
equalizeHist(src, dst);
imshow("src", src);
imshow("dst", dst);
waitKey();

在这里插入图片描述

参考文献:

  1. OpenCV官方文档:https://docs.opencv.org/4.x/
  2. 《OpenCV3编程入门》毛星云、冷雪飞等编著
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值