【OpenCV入门】一些基本的图像处理
我的个人博客:谋仁·Blog
微信公众号:谋仁的麻袋
一些概念
颜色空间
为了表示一种特定的颜色,我们通常建立一维、二维、三维甚至四维空间坐标来表示,这种坐标系统所能定义的色彩范围即颜色空间。下面列举常见的颜色空间:
RGB模型
RGB模型将颜色编码成(R,G,B)即(Red红,Green绿,Blue蓝)。每个分量范围是[0,255]共256级。因此,RGB模型可以表示256×256×256≈1670万种颜色。
注意:在OpenCV中存储顺序不是RGB,而是BGR。单通道模型
单通道图即灰度图,图片像素颜色由一维的值来表示,分量范围是[0,255]。0是黑色,255是白色,中间是不同程度的灰色。二值模型
二值图像即黑白图像,每个像素的颜色由一维的值来表示,分量范围是[0,1],0代表黑色,1代表白色。HSV模型
HSV模型由三个参数来表示颜色:色调(H)、饱和度(S)、明度(V)。
色调(H)用角度表示,范围[0°,360°],红色为0°,从红色开始按逆时针方向计算。(如下图)
饱和度(S)表示颜色接近光谱色的程度,饱和度越高,颜色越深而艳。取值范围[0%,100%]。
明度(V)表示颜色鲜亮的程度,取值范围[0%,100%],0%为黑色,100%为白色。
Lab模型
Lab颜色空间中的L分量用于表示像素的亮度,取值范围是[0,100],表示从纯黑到纯白;a表示从红色到绿色的范围,取值范围是[127,-128];b表示从黄色到蓝色的范围,取值范围是[127,-128]。图示如下:
图像的深度
图像用于存储像素的值占得比特(bit)位数(就是转换为二进制的位数),就是图像的深度。例如:在二值模型中每个像素点的值是一维的,且取值范围是[0,1],所以仅用一位比特位就可以满足,图像深度为1;RGB模型中每个像素用R,G,B三个分量表示,每个分量取值范围[0,255],用8位可以表示,所以像素深度总共为24位。
图像通道
为了储存像素数据,每一个像素点用一个或多个分量来存储数据,分量的数量就是图像通道。例如,RGB模式中每个像素点由Red、Dreen、Blue三个分量来表示,每个取值范围都是[0,255],这个图像通道就是3。灰度图仅用一个取值范围为[0,255]数值来表示,灰度图的图像通道就是1。
颜色空间的转换-cvtColor
函数cvtColor
cv::cvtColor()作用是将图像从一个颜色空间转换到另一个颜色空间。并且在转换的过程中能够保证数据的类型不变,即转换后的图像的数据类型和位深与源图像一致。
函数定义:
1 | void cv::cvtColor( |
- src: Mat类,输入待转换的图像
- dst:Mat类,转换后新图像放在这里
- code:转换的代码或标识,即图像转换的格式(模式1→模式2)
OpenCV提供的映射:
- dstCn:(默认是0)目标图像通道数,如果取值为0,则由src和code决定
示例(BGR转换成灰度图)
源代码:
1 |
|
运行结果:
高斯滤波-GaussianBlur
函数GaussianBlur
函数的定义:
1 | void GaussianBlur( InputArray src, //输入的图像 |
- src:Mat类,输入待处理的图像
- dst:Mat类,输出与原图大小和类型相同的图像
- ksize:高斯内核的大小,决定了滤波的程度。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数。或者,它们可以是零的,它们都是由sigma计算而来
- sigmaX:高斯核函数在X方向上的标准偏差
- sigmaY:高斯核函数在Y方向上的标准偏差,如果sigmaY是0,则函数会自动将sigmaY的值设置为与sigmaX相同的值,如果sigmaX和sigmaY都是0,这两个值将由ksize.width和ksize.height计算而来
- borderType:推断图像外部像素的某种便捷模式,有默认值BORDER_DEFAULT,如果没有特殊需要不用更改
示例
源代码:
1 |
|
运行结果:
图像边缘检测-Canny
函数Canny
函数定义
重载1:
1 | void Canny( InputArray image,//输入图像 |
两个阈值参数:
- 低于阈值1的像素点会被认为不是边缘;
- 高于阈值2的像素点会被认为是边缘;
- 在阈值1和阈值2之间的像素点,若与第2步得到的边缘像素点相邻,则被认为是边缘,否则被认为不是边缘
- 建议上限是下限的2或3倍
apertureSize参数:
- 为Sobel()运算提供内核大小,默认值为3
重载2:
1 | void Canny( InputArray dx, |
1 |
|
运行结果:
图像的膨胀和侵蚀-dilate和erode
函数dilate/erode
dilate函数的定义
1 | void dilate( InputArray src, |
erode函数的定义
1 | void erode( InputArray src, |
两个函数参数完全一样,参数解释:
- src:Mat类,输入的原图
- dst:Mat类,用于存放处理后的图像
- kernel:用于膨胀/侵蚀操作的结构元素,当为NULL时,那么默认使用一个3 x 3 的方形结构元素,可以使用getStructuringElement()(下文有详细介绍)来创建结构元素
- anchor:结构元素的锚点位置,默认值value(-1,-1)表示锚点位于结构元素中心
- iterations:进行膨胀/侵蚀操作迭代执行的次数,默认是1
- borderType:用于推断图像外部像素的某种推断模式。默认值BORDER_CONSTANT
- Scalar& borderValue:边缘值,默认值morphologyDefaultBorderValue()。一般不用改动
补充:函数getStructuringElement
函数的定义:
1 | Mat getStructuringElement(int shape, |
作用:返回(Mat类型)指定形状和尺寸的结构元素
参数解释:
- shape:结构元素的形状
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE; - ksize:结构元素的尺寸,同GaussianBlur函数的ksize
- anchor:锚点的位置,默认值Point(-1,-1),表示锚点位于中心点
示例
源代码:
1 |
|
运行结果: