1.图像基本操作之读取、显示和存储图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stdafx.h"
#include "opencv.hpp" //引用相关头文件
int main()
{
cv::Mat img,imgGaussian; //创建图像变量
img = cv::imread("D:/image/lane.bmp", cv::IMREAD_COLOR); //读取图像
if (img.empty()) return -1; //使用cv::Mat类的empty方法判断是否正确读
//取了图像,如果读取失败,则退出程序
int width = img.cols; //获取宽高,图像是二维矩阵,因而可以通过列数与行数,即
int height = img.rows; //cols和rows
cv::GaussianBlur(img,imgGaussian,cv::Size(55),00); //高斯滤波
cv::namedWindow("Gaussian",cv::WINDOW AUTOSIZE);//创建窗口
cv::imshow("Gaussian",imgGaussian); //显示图像
cv::waitKey(0); //窗口停留
cv::imwrite("gaussianfilter.bmp",imgGaussian); //保存图像
cv::destroyWindow("Gaussian"); //销毁窗口
return 0;
}

原函数解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cv::Mat cv::imread (const String & filename,int flags = IMREAD COLOR)
/*
函数参数:
filename:图像文件名。
flags:读取时使用的色彩模式标志位,从cv::imreadModes中取值,1为源图彩色模式,0为灰度模式。

支持读取的图像文件类型:
Windows bitmaps:*.bmp、*.dib(全部支持)。
JPEG files:*.jpeg、*.jpg、*.jpe(部分支持)。
JPEG 2000 files:*.jp2(部分支持)。
Portable Network Graphics:*.png(部分支持)。
WebP:*.webp(部分支持)。
Portable image format : *.pbm 、 *.pgm 、 *.ppm 、 *.pxm 、*.pnm(全部支持)。
Sun rasters:*.sr、*.ras(全部支持)。
TIFF files:*.tiff、*.tif(部分支持)。
OpenEXR Image files:*.exr(部分支持)。
Radiance HDR:*.hdr、*.pic(全部支持)。
Raster and Vector geospatial data supported by Gdal(部分支持)。
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
void cv::GaussianBlur(InputArray src,OutputArray dst,Size ksize,double sigmax,double sigmaY=0int borderType = BORDER DEFAULT)
/*
说明:高斯滤波是一种常见的低通滤波器,它能抑制输入图像的高频分量(图像的边缘和细节信息),保留低频分量(图像中变化缓慢的部分)。因此,通过高斯滤波可以得到一幅边缘模糊的图像。

函数参数:
src:输入图像。图像可以拥有多个通道,每个通道在滤波时都独立处理。图像位深度必须是CV_8U、CV_16U、CV_16S、CV_32F或CV_64F,分别表示8位无符号整型、16位无符号整型等。
dst:输出图像。与输入图像的类型和大小相等。
ksize:高斯核尺寸。高斯核的高和宽可以不同,但必须是奇数或零。如果是零,则可通过sigma参数计算得到。cv::Size表示数据类型,高斯核尺寸越大,模糊程度越高。
sigmaX:高斯核在x轴上的标准差。
sigmaY:高斯核在y轴上的标准差。如果sigmaY为0,则被设置为与sigmaX相等。如果两个sigma的参数都为0,则高斯核在x轴和y轴上的标准差将分别通过ksize.width参数和ksize.height参数计算得
到。
borderType:像素外插法,用来定义在指定滤波时如何处理图像边界。
*/
1
2
3
4
5
6
7
8
9
10
bool cv::imwrite(const String & filename,InputArray img,onst std::vector< int > & params = std::vector< int >())
/*
说明:cv::imwrite函数既可以将图像存储为指定格式的图像文件;也可以使用FileStorage I/O功能将图像保存为XML或YAML格式。如果不在cv::imwrite函数的参数中指定存储路径,则存储的文件与main函数在同一目录中。
cv::imwrite函数实现了把图像存储为指定格式的文件的功能,存储格式从文件扩展名获取。当使用此函数将图像保存成.png、.jpeg或.tiff格式的文件时,只有位深度为8位或16位无符号整型数据,且单通道或3通道(通道顺序为BGR)的图像才可以。如果图像数据不满足上述要求,则可以使用cv::Mat::convertTo和cv::cvtColor函数把图像转换成可存储的格式。此外,cv::imwrite函数还支持把图像存储为透明图像(.png格式)。

函数参数:
filename:文件存储路径,包含文件扩展名。
img:待存储的图像。
params:与存储格式相关的参数对,如压缩比等。参数类型为std::vector<int> 。 参数构成方式如 下:(paramId_1,paramValue_1, paramId_2, paramValue_2, …)
*/

2.图像基本操作之颜色空间转换

颜色空间又称为彩色模型或彩色系统,其目的是在某些标准下用通常可以接受的方式方便地对彩色进行说明。在数字图像处理中,最通用的面向硬件的是RGB(红、绿、蓝)空间,该空间用于彩色监视器和彩色摄像机;CMY(青、洋红、黄)空间和CMYK(青、洋红、黄、黑)空间针对彩色打印机;HSI(色调、饱和度、亮度)空间是一种更符合人描述和解释颜色的一种模型。HSI空间还有一个优点,即它可以解除图像中的颜色和灰度信息的联系,使其更适合某些灰度处理技术,并且对样本量需求较大的机器学习算法而言,还可以通过改变色调和饱和度的方式增加样本数量,提高训练出来的空间对不同光照条件下的稳健性。

HSI(色调、饱和度和亮度)空间可以从彩色图像携带的彩色信息(色调和饱和度)中消去强度分量的影响。因此,HIS空间对于开发基于彩色描述的图像处理算法来说是一个理想的彩色空间。在某些基于深度学习的分类识别任务中,通常将原始图像转换成HSI空间来削弱光线变化的影响,增强算法的稳健性。

HSI空间的色调、饱和度和亮度可以从RGB空间的立方体中得到,也就是说,可以把任何一个RGB空间中的点转换为对应的HSI空间中的点 。值得注意的是,在OpenCV中可以使用HSV(色调、饱和度和值)空间来隔离图像颜色与亮度信息。

图像没有色彩信息,只有亮度信息,通常使用灰度图表示,例如红外图像。灰度空间是视觉机器学习任务中最基本也是最常用的颜色空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include"stdafx.h"
#include"opencv.hpp"
using namespace std;
int main()
{
cv::Mat img_rgb,img_gray, img_hsv, img_gray2rgb,img_hsv2rgb;
img_rgb = cv::imread("D:/image/lane.bmp",cv::IMREAD_COLOR);
//颜色空间转换
cv::cvtColor(img_rgb,img_hsv,cv::CV_BGR2HSV);
cv::cvtColor(imq_hsv,img_hsv2rgb,cv::CV_HSV2BGR);
cv::cvtColor(img_rgb,img_gray,cv::CV_BGR2GRAY);
cv::cvtColor(img_gray,img_gray2rgb,cv::CV_GRAY2BGR);
return 0;
}

原函数解读:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void cv::cvtColor(InputArray srCr,OutputArray dstint code,int dstCn=0)
/*
cv::cvtColor函数将输入的源图从某个颜色空间转换至另一个颜色空间。OpenCV的默认颜色空间为BGR(即RGB颜色空间中R与B分量交换位置),因此对于一个标准的24bit彩色图,第一字节为8bit蓝色分量,第二字节为8bit绿色分量,第三字节为8bit红色分量,第4、5、6字节表示下一个像素的蓝色、绿色和红色分量,依此类推。

函数参数:
src:输入图像,可以是8位无符号整型(CV_8U)、16位无符号整型(CV_16U)或单精度浮点型数据。
dst:输出图像,与输入图像的类型、大小和位深度均相等。
code:颜色空间转换码,指定颜色空间转换的类型。
dstCn:目标图像的通道数。当dstCn为0时,通道数将根据code与源图通道数自动确定。
注意:cv::cvtColor函数对R、G、B通道数据转换的范围如下。
CV_8U类型图像:0~255。
CV_16U类型图像:0~65535。
CV_32F类型图像:0~1。

RGB空间与HSV空间可以进行可逆转换,但把RGB空间转成灰度空间后,再转换回RGB空间,颜色分量信息就会丢失,即灰度和彩色之间的转换是不可逆的。
*/

3.图像基本操作之几何变换

图像的平移、缩放、镜像和旋转都属于几何变换。在几何变换钟可将一幅图像上的像素重新定位到新位置,则需要使用内插对这些新位置上的像素赋值。从根本上看,内插是用已知数据估计未知位置的数据。常见的插值算法有最邻近插值、双线性插值、二次立方插值和三次立方插值等。

把最靠近该网格的原始图像的像素灰度值作为该网格的灰度值,就是最邻近插值,又称为零阶内插。这种插值算法速度快,但是效果不佳,会产生棋盘格效应,当放大倍数很高时,棋盘格效应明显。采用4个最邻近点的双线性插值,对于日常图像缩放而言,双线性插值是首选算法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "stdafx,h"
#include "opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
cv::Mat image =cv::imread("D:/image/lane.bmp",cv::IMREAD_COLOR);//读取原始图像
//尺度变换
cv::Mat resize_image, resize_image_M;
cv::resize(image,resize_image,cv::size(0,0),0.50.51);

cv::Mat warp_matrix_resize; //声明尺度变换M矩阵
warp_matrix_resize = cv::Mat::zeros(23,CV 32F);
float cx=0.75,cy=0.5; //设置尺度变换 M矩阵
warp_matrix_resize.at<float>(00) = cx;
warp_matrix_resize.at<float>(11) = cy;
cv::Size dsize = image.size();
dsize.width *= cx;
dsize.height *= cy;
warpAffine(image,resize_image_M,warp_matrix_resize,dsize,INTER LINEAR,1);

//平移变换
cv::Mat temp_image=resize_image.clone(); //使用缩小后的图像进行变换
cv::Mat translation_image; //声明目标图像变量
cv::Mat warp_matrix_translation; //声明平移变换M矩阵
warp_matrix_translation = cv::Mat::eye(23,CV 32F);
float tx=40,ty=20;//设置平移变换参数
warp_matrix_translation.at<float>(02) = tx;
warp_matrix_translation.at<float>(12) = ty;
int top =0,bottom = ty, left =0,right = tx;
cv::copyMakeBorder(temp_image, temp_image,top,bottom,left,right, BORDER_CONSTANT,cv::Scalar(200));//扩边
cv::warpAffine(temp_image, translation_image, warp_matrix_translation,temp image.size(),INTER LINEAR,BORDER_TRANSPARENT);

//旋转变换
cv::Mat rotate_image; //声明目标图像变量
temp_image= resize_image.clone();
double angle=45;//设定旋转角度
int border=0.207 * temp_image.cols;
cv::copyMakeBorder(temp_image, temp_image, border, border, border,border, BORDER_CONSTANT,cv::Scalar(200));//扩边
cv::Point2f center(temp_image.cols / 2., temp_image.rows / 2.);//指定旋转中心
cv::Mat warp_rotate_matrix = cv::getRotationMatrix2D(center, angle, 1.0);//获取旋转变换 M矩阵
//根据旋转矩阵进行仿射变换
cv::warpAffine(temp_image, rotate_image, warp_rotate_matrix,temp_image.size(),INTER_LINEAR,BORDER_REPLICATE);

//剪切变换
cv::Mat shear_vertical_image,shear_horizontal_image;//声明目标图像变量
temp_image= resize_image.clone();
cv::Mat temp_image_vertical,temp_image_horizontal;
border=40;
cv::copyMakeBorder(temp_image, temp_image_vertical,10,2* border, border,10 +border,BORDER_CONSTANT,cv::Scalar(200));
cv::copyMakeBorder(temp_image, temp_image_horizontal, border + 10, border,102*border,BORDER_CONSTANT,cv::Scalar(200));
cv::Mat warp_matrix_shear_vertical, warp_matrix_shear_horizontal;//声明剪切变换 M 矩阵
warp_matrix_shear_vertical = cv::Mat::eye(23,CV 32F);//垂直剪切变换矩阵
warp_matrix_shear_horizontal = cv::Mat::eye(23,CV 32F);//水平剪切变换矩阵
float sv=0.3,sh=0.3;
warp_matrix_shear_horizontal.at<float>(01)=sh;//水平偏移矩阵
warp_matrix_shear_vertical.at<float>(10) = sv; //垂直偏移矩阵
cv::warpAffine(temp_image_vertical,shear_vertical_image,warp_matrix_shear_vertical,temp_image vertical.size(),INTER_LINEAR,BORDER_REPLICATE);
cv::warpAffine(temp_image_horizontal, shear_horizontal_image,warp_matrix_shear_horizontal,temp_image horizontal.size(),INTER_LINEAR,
BORDER_REPLICATE);
return0;
}

原函数解读:

1
2
3
4
5
6
7
8
9
10
11
void cv::resize (InputArray src, OutputArray dst,Size dsize,Double fx=0,Double fy=0,Int interpolation = INTER_LINEAR)
/*
函数参数:
src:输入图像。
dst:输出图像。当dsize不为0时,输出图像与输入图像的尺寸相同。
dsize:输出图像尺寸。如果输入dsize为0,则计算方式为:dsize = cv::Size(round(fx*src.cols),
round(fy*src.rows)),fx和fy两组参数不能全为0。
fx:水平轴缩放比例因子。如果输入fx=0,则计算方式为:(double)dsize.width/src.cols
fy:垂直轴缩放比例因子。如果输入fy=0,则计算方式为:(double)dsize.height/src.rows
interpolation:插值算法。
*/
1
2
3
4
5
6
7
8
9
10
11
void cv::warpAffine(InputArray src,OutputArray dstInputArray M,Size dsize,int flaqs = INTER LINEAR,int borderMode = BORDER_CONSTANT,const Scalar & borderValue = Scalar())
/*
函数参数:
src:输入图像。
dst:输出图像,与输入图像的尺寸和类型相同。
M:2×3变换矩阵。
dsize:输出图像尺寸。
flags :组合标志位。插值算法和可选标志表示M是(dst→src)逆变换。
borderMode:像素外推方法。旋转、平移和剪切等变换会造成目标图像中的某些区域没有像素值,此时需要用到像素外推方法(又称为边界填充方法)来填补这些“空白”区域。当borderMode = BORDER_TRANSPARENT时,意味着此函数不会修改与源图像中“域外值”对应的目标图像中的像素。
borderValue:在边界为恒定值的情况下使用的数值,默认为0。
*/
1
2
3
4
5
6
7
8
9
cv::Mat getRotationMatrix2D(Point2f center, double angle, double scale);
/*
函数参数:
center: 旋转中心坐标(图像左上角点为坐标原点)
angle: 旋转角度(以°为单位)
scale: 比例因子,scale=1.0表示在旋转时不做缩放操作。

cv::getRotationMatrix2D函数获取的旋转变换矩阵默认为绕旋转中心逆时针旋转。
*/