1、访问图像的各个像素强度
当我们处理图像时,有时会需要访问特定位置的像素强度值,当我们想要改变一组像素的亮度或对比度或者想执行一些其他像素级操作时,这就非常有用。对于8位灰度图像来说,一个点的强度值在0到255范围内;而对于具有蓝色、绿色和红色三个通道的彩色图像,每个点都具有三组不同的强度值,每一组的值都在0到255之间。
OpenCV提供一个cv::Mat::at<>方法,可以访问各个通道图像里特定位置的强度值。它需要一个参数,就是要访问强度值的点位置,这里使用带有行列值作为参数的Point类来传递该点位置。对于灰度图像,这个方法将返回一个标量对象;对于彩色图像,它将返回三个强度值的矢量。用于访问灰度及彩色图像中特定位置以获得该像素强度的代码如下:
首先读取灰度图像,然后在该图像对象上调用at方法,测量点(100,50)的强度值,表示第100行和第50列处的像素,然后得到一个返回的标量,存储在强度变量中,将这个值显示在控制台上。彩色图像遵循相同的程序,但返回值是三个强度的矢量,存储在Vec3b对象中,强度值显示在控制台上。上述程序的输出:
2、OpenCV中直方图的计算和均衡
直方图是图像的一个非常重要的属性,因为它提供该图像外观的全局描述。可以从直方图获得大量信息,包括表示图像中灰度级出现的相对频率,基本上由是X轴上的灰度级与Y轴上每个灰度级的像素数量所组成。如果直方图集中在左侧,则图像将非常暗;如果它集中在右侧,则图像将非常亮。通常应该是均匀分布,能得到较好视觉效果。
完美图像在其所有灰度级中具有等量的像素,因此在整个范围内直方图应在较大的动态范围里有相同数量的像素,这可以通过直方图均衡的技术来实现,这是所有计算机视觉应用中非常重要的预处理步骤。
以下代码描述灰度图像上直方图均衡的过程:
将读取的图像上载到设备显存里,准备进行直方图均衡。由于这是个计算密集的步骤,因此CUDA加速将有助于提高程序的性能。OpenCV为直方图均衡提供equalizeHist函数,需要两个参数:第一个参数是源图像,第二个参数是目标图像。然后将目标图像下载回主机,并显示在控制台上。直方图均衡后的输出如图
可以看出,经过直方图均衡的图像比原始图像的视觉质量更好。
直方图均衡也可以在彩色图像上完成,而且必须在个别通道上进行,因此彩色图像必须分成三个通道,每个通道各自执行直方图均衡,然后合并通道再重建图像。以下代码描述彩色图像上直方图均衡的过程:
BGR颜色空间的直方图通常不太均衡,HSV和YCrCb颜色空间可以辅助处理,因此代码中先将BGR颜色空间转为HSV颜色空间,然后使用split函数将其拆分为三个独立的通道。如此一来,色调和饱和度通道包含颜色信息,这两个通道没有需要均衡的地方,直方图只要针对值通道进行均衡就行,然后再使用merge函数将三个通道合并,重建彩色图像。最后将HSV彩色图像转换回BGR颜色空间,用imshow显示出来。本段代码执行的输出如图:
总的来说,直方图均衡能提高图像的视觉质量,因此对于所有计算机视觉应用来说都是非常重要的预处理步骤。
3、图像的几何变换
计算机视觉应用中,调整图像大小、平移和旋转图像都是经常需要的功能。
3.1、图像大小调整
在某些计算机视觉应用中,图像需要符合指定尺寸,因此需要将任意大小的图像转换成指定尺寸。OpenCV提供调整图像大小的功能。图像大小调整的代码如下:
如代码所示,这里有两个不同函数可以获取图像的高度和宽度:Mat对象的rows和cols属性分别描述图像的height和width;Mat对象也可以用查找图像大小的size()方式来获取height和width属性。图像以两种方式调整大小:在第一种方式中,图像大小调整为(200,200)这个特定尺寸;第二种方式,调整为原始尺寸的一半。OpenCV为此操作提供resize函数,需要四个参数。
前两个参数分别是源图像和目标图像,第三个参数是目标图像的大小,是使用Size对象定义的。调整图像大小时,必须在源图像中插入像素值以生成目标图像,这里有多种插值方法,诸如双线性插值、双三次插值、区域插值等都可用来作为像素的插值。这些插值方法作为resize函数的第四个参数,可以是cv::INTER_LINEAR(双线性)、cv::INTER_CUBIC(双三次)或cv::INTER_AREA(区域)。图像大小调整代码的输出如图:
注意:不同的插值方法也会带来速度的衰减,三线性插值相对比较慢的。
3.2、图像平移与旋转
图像平移与旋转在一些计算机视觉应用中是重要的几何变换,OpenCV提供一个简单的API来对图像执行这些变换。执行平移与旋转的代码如下:
在代码中,使用Mat对象创建此矩阵,其中70作为x方向的偏移量、50作为y方向的偏移量。此矩阵作为参数传递给warpAffine函数以进行图像平移,warpAffine函数的其他参数分别是源图像、目标图像和输出图像的大小。
旋转过程则需要创建一个旋转矩阵,以特定点为中心,对图像执行特定角度的图像旋转。OpenCV提供cv::getRotationMatrix2D函数来构造这个旋转矩阵,这个函数需要三个参数:第一个参数是旋转点,也就是图像旋转中心;第二个参数是以度为单位的旋转角度,本范例指定为45度;最后一个参数是尺度(scale),本范例指定为1。然后将构造的旋转矩阵作为参数传递给warpAffine函数,以进行图像旋转。
图像平移和图像旋转程序的输出: