使用opencv来分析地图中用到的一些函数记录
- 灰度图
- 读图像
- 图像二值化
- 显示图像
- 形态学滤波:腐蚀和膨胀
- 形态学滤波:开运算,闭运算,形态学梯度,顶帽,黑帽
灰度图
灰度图,Gray Scale Image 或是Grey Scale Image,又称灰阶图。把白色与黑色之间按对数关系分为若干等级,称为灰度。灰度分为256阶。
黑色:0 白色:255
读图像
Mat src=imread("/home/daniel/map/merge/map.pgm");
imread函数形式:
Mat imread( const string& filename, int flags=1 )
{
Mat img;
imread_( filename, flags, LOAD_MAT, &img );
return img;
}
CV_LOAD_IMAGE_UNCHANGED:等价取值为-1,这个标识在新版本中已经被废置,忽略。
CV_LOAD_IMAGE_GRAYSCALE: 等价取值为0,始终将图像转换成灰度再返回。
CV_LOAD_IMAGE_COLOR:等价取值为1,总是转换图像到彩色再返回。
CV_LOAD_IMAGE_ANYDEPTH: 等价取值为2,如果载入的图像的深度为16位或者32位,就返回对应深度的图像,否则则转换为8位深度图像再返回。
enum
{
CV_LOAD_IMAGE_UNCHANGED = -1,
CV_LOAD_IMAGE_GRAYSCALE = 0,
CV_LOAD_IMAGE_COLOR = 1,
CV_LOAD_IMAGE_ANYDEPTH = 2,
CV_LOAD_IMAGE_ANYCOLOR = 4
}
图像二值化
第一个函数是彩色图像转化为灰度图像:cvtColor函数;
下一个函数是由灰度图转化为二值图像函数:threshold函数
cvtColor函数原型:
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )
src和dst分别是待转的图像(src)和待转图像转换后的图像(dst)
code是一个掩码,表示由src到dst之间是怎么转的,比如是彩色转为灰度,还是彩色转为HSI模式
最后的dstCn表示dst图像的波段数,这个值默认是0,它可以从参数code中推断
code的模式包括:
CV_RGB2GRAY:<彩色图像—灰度图像>
CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB
CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB
更多变换模式详解opencv官方文档
double cv::thresold(inputArray src,
OutputArray dst,
double thresh,
double maxval,
int type)
src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者由区别)
dst:输出图像
thresh:阈值
maxval:dst图像中最大值
type:阈值类型
破折线为将被阈值化的值;虚线为阈值
cv2.THRESH_BINARY 大于阈值的部分被置为maxval,小于部分被置为0
cv2.THRESH_BINARY_INV 大于阈值部分被置为0,小于部分被置为maxval
cv2.THRESH_TRUNC 大于阈值部分被置为threshold,小于部分保持原样
cv2.THRESH_TOZERO 小于阈值部分被置为0,大于部分保持不变
cv2.THRESH_TOZERO_INV 大于阈值部分被置为0,小于部分保持不变
还有很重要的cv2.THRESH_OTSU 作为图像自适应二值化的一个很优的算法Otsu
简单代码示例:
Mat src_gray;
cvtColor(src,src_gray,CV_BGR2GRAY);
Mat src_th;
threshold(src_gray,src_th,230,255,THRESH_BINARY_INV);
显示图像
imshow函数介绍
函数功能:在指定窗口中显示图像。
函数原型:void imshow(const string& winname, InputArray mat);
imshow("image4",src);
形态学滤波:腐蚀和膨胀
形态学操作:就是基于形状的一系列图像处理操作。最基本的形态学操作有两种,膨胀(dilate)和腐蚀(erode)
膨胀和腐蚀的主要功能如下:
- 消除噪声
- 分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素
- 寻找图像中的明显的极大值区域和极小值区域
- 求出图像的梯度
注意:腐蚀和膨胀是对白色部分(高亮部分)而言的。
相关的核心API函数:
膨胀:dilate函数
void dilate(
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue()
);
- 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
- 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
- 第三个参数,InputArray类型的kernel,膨胀操作的核。若为NULL时,表示的是使用参考点位于中心3x3的核。
我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:
矩形: MORPH_RECT
交叉形: MORPH_CROSS
椭圆形: MORPH_ELLIPSE
而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。
我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。
Mat kernel=getStructuringElement(MORPH_RECT,Size(10,10),Point(-1,-1));
- 第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。
- 第五个参数,int类型的iterations,迭代使用dilate()函数的次数,默认值为1。
- 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
- 第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。
Mat src_morph;
Mat kernel=getStructuringElement(MORPH_RECT,Size(10,10),Point(-1,-1));
dilate(open_result,src_morph,kernel,Point(-1,-1),1);
腐蚀:erode函数
与dilate函数一样的参数定义:只是将dilate函数换成erode函数
Mat src_morph;
Mat kernel=getStructuringElement(MORPH_RECT,Size(10,10),Point(-1,-1)); //膨胀8个像素
erode(open_result,src_morph,kernel,Point(-1,-1),1);
形态学滤波:开运算,闭运算,形态学梯度,顶帽,黑帽
开运算:先腐蚀后膨胀的过程。
闭运算:先膨胀后腐蚀的过程。
形态学梯度:膨胀图与腐蚀图之差。
顶帽:原图与开运算效果图之差。
黑帽:闭运算与原图之差。
各种运算的作用:
- 开运算 :可以用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。/ 可以清除一些小东西(亮的),放大局部低亮度的区域
- 闭运算 :可以清除小黑点
- 形态学梯度:提取物体边缘
- 顶帽:突出原图像中比周围亮的区域
- 黑帽:突出原图像中比周围暗的区域
核心API函数:
void morphologyEx(
InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor=Point(-1,-1),
int iterations=1,
int borderType=BORDER_CONSTANT,
const Scalar& borderValue=morphologyDefaultBorderValue() );
第一个参数:src输入图像,图像位深应该为以下五种之一:CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。
第二个参数:dst输出图像,需和源图片保持一样的尺寸和类型。
第三个参数:op表示形态学运算的类型:
MORPH_OPEN – 开运算(Opening operation)
MORPH_CLOSE – 闭运算(Closing operation)
MORPH_GRADIENT - 形态学梯度(Morphological gradient)
MORPH_TOPHAT - 顶帽(Top hat)
MORPH_BLACKHAT - 黑帽(Black hat)
MORPH_ERODE - 腐蚀
MORPH_DILATE - 膨胀
第四个参数:kernel形态学运算的内核。为NULL,使用参考点位于中心3x3的核。一般使用函数getStructuringElement配合这个参数的使用, 前面讲过
第五个参数:anchor锚的位置,其有默认值(-1,-1),表示锚位于中心。
第六个参数:iterations迭代使用函数的次数,默认值为1。
第七个参数:borderType用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_CONSTANT。
第八个参数:borderValue当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。
简单代码示例
//自定义核
Mat element=getStructuringElement(MORPH_RECT,Size(5,5));
//开运算 去掉杂点
Mat open_result;
morphologyEx(src_th,open_result,MORPH_OPEN,element);