OpenCV4学习笔记(7)——图像翻转与插值

本次要整理记录的内容是:图像的翻转和图像插值。

  1. 图像翻转
    图像的翻转是经常用到的一个小功能,尤其是在调用摄像头获取图像的时候,常常发现得到的图像是左右颠倒的,有强迫症的人看起来就极其难受,所以在获取一帧图像后常常要进行翻转后再显示出来,那看起来就舒服得多了。
    而这个小功能实现起来也并不困难,我们可以通过遍历像素点来尝试着实现这个功能,代码如下:
Mat image_flipX, image_flipY, image_flipXY;
int height = image.rows;
int width = image.cols;
Mat dst = Mat::zeros(image.size(), image.type());
for (int row = 0; row < height; row++)
{
	for (int col = 0; col < width; col++)
	{
		Vec3b bgr = image.at<Vec3b>(row, col);
		//dst.at(row, width - col - 1) = bgr;				//遍历像素点实现图像沿Y轴翻转
		dst.at<Vec3b>(height - row - 1, col) = bgr;				//遍历像素点实现图像沿X轴翻转
	}
}
imshow("dst", dst);

我们先定义一个Mat对象dst用来作为最后的显示图像,初始化为和原图的size、type都相等的全黑色图像。然后用两个for循环分别对高height、宽width进行遍历,每访问到原图中坐标为(row, col)的像素点,就将它的三通道像素值以Vec3b的格式返回出来,赋值给一个Vec3b类的对象bgr。
(注意:Vec3b是一个包含三个元素的向量,一般用来获取RGB图像的三通道像素值并保存起来。每一个Vec3b对象中,按照B、G、R的顺序存放三通道值。)
随后将bgr赋值给显示图像dst中坐标为(row, width - col - 1)的像素点。其中将(row, col)坐标点的值赋给(row, width - col - 1)坐标点,其实就是将图像沿着Y轴翻转了过去,可以想象为一本书翻页的过程,Y轴就是书的中间连接部分,将书页翻过去的过程就相当于图像沿着Y轴的翻转过程。
那么以同样的方式,只将(row, width - col - 1)改为(height - row - 1, col),就可以实现图像沿X轴的翻转。
这是通过遍历像素点的方式来实现图像翻转,实际上OpenCV提供了一个简单的API:flip(),来实现这个功能。

	flip(image, image_flipX, 0);			//沿x轴翻转
	flip(image, image_flipY, 1);			//沿y轴翻转
	flip(image, image_flipXY, -1);			//沿xy轴翻转

很明显,使用API可就要比自己实现简单多了,只需要略微注意一下参数的传入即可。
第一个参数是输入图像,也就是想要进行翻转的图像;
第二个参数就是输出图像;
第三个参数是表示翻转的方式,如果传入值为0,则表示沿X轴翻转,传入值为1则表示沿y轴翻转,传入值为-1则表示将图像沿原点翻转,也可以理解成先沿X轴、再沿Y轴翻转。
特别要注意的是在一幅图像中,默认情况下原点(0, 0)是左上角的点,X轴指向图像的右边,Y轴指向下边
效果如下:

  1. 图像插值
    图像的插值主要是在缩放图像、透视变换、旋转等等情况下使用的,可以理解为是图像在变换过程中由于某些原因导致图像中的某些像素点的值为空,所以需要把这些空点给补上去,计算机就会根据该点邻域的像素值来重新计算出一个值并赋给这个点,也就是把一个像素值插入到该像素点上,所以这种操作被称为插值。
    插值方式有很多种,最常见四种插值算法:
    1、INTER_NEAREST----邻近点插值
    2、INTER_LINEAR----线性插值
    3、INTER_CUBIC—双立方插值(反锯齿功能)
    4、INTER_LANCZOS4 —基于像素权重求得平均像素值的插值算法

    这些插值算法的背后其实都是一套套的数学公式和计算方法,在此我就不深究了(其实是我没有自己去推导过,只了解了大概的原理)。
    这些算法的效果和速度一般都是成反比的,插值效果越好其运行速度越慢,所以在使用的时候需要根据具体需求选取不同的算法。其中第一种邻近点插值并不推荐使用,因为它是直接将最接近点的像素值来赋给插值点,这样形成的效果会很差,当然速度也很快。最好是使用INTER_CUBIC方法,也就是双立方插值算法,其效果还是比较不错的,而且还具有一定的反锯齿效果,能够使得插值后的图像没有那么强烈的撕裂感。
    插值用的最多的应该是缩放图像的时候resize(image, image, Size(), 2, 2, INTER_CUBIC)
    第一个参数为输入图像,第二个参数为输出图像;
    第三个参数为要将输入图像缩放到的规定尺寸,可以为空Size(),如果size有值,使用size做放缩插值,否则根据fx与fy;
    第四、五个参数是在X、Y方向的放缩系数,也就是放大或者缩小多少倍;
    第六个参数就是选择的插值算法了。

应该根据需求来选择合适的插值方式,既要使得插值效果尽量的好,又要在运行速度上不能太慢,这就需要码字的去一点一点尝试咯。

本次就整理记录到此~~~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

你可能感兴趣的:(学习笔记)