opencv学习笔记(二十)——形态学滤波
2015-11-17 15:14
603 查看
开运算
处理过程:先腐蚀后膨胀。功能:用于消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积,同时抑制比结构元小的亮细节。
使用实例:
#include<opencv2/opencv.hpp> void main() { cv::Mat image = cv::imread("腐蚀膨胀练习1.jpg"); cv::namedWindow("SourceImage"); cv::namedWindow("OutputImage"); cv::imshow("SourceImage", image); //开运算(MORPH_OPEN) cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); cv::morphologyEx(image, image, cv::MORPH_CLOSE, element); cv::imshow("OutputImage", image); cv::waitKey(0); }
效果图如下:
闭运算
处理过程:先膨胀后腐蚀功能:用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积,同时抑制比结构元小的暗细节。
使用实例:
#include<opencv2/opencv.hpp> void main() { cv::Mat image = cv::imread("result.BMP"); cv::namedWindow("SourceImage"); cv::namedWindow("OutputImage"); cv::imshow("SourceImage", image); //闭运算(MORPH_CLOSE) cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5)); cv::morphologyEx(image, image, cv::MORPH_CLOSE, element); cv::imshow("OutputImage", image); cv::waitKey(0); }
效果:
形态学梯度
处理过程:膨胀图和腐蚀图相减功能:对二值化图像进行这一操作可以将边缘突出来,可以使用形态学梯度来保留物体的边缘轮廓
使用实例:
#include<opencv2/opencv.hpp> void main() { cv::Mat image = cv::imread("result.BMP"); cv::namedWindow("SourceImage"); cv::namedWindow("OutputImage"); cv::imshow("SourceImage", image); //形态学梯度(MORPH_GRADIENT) cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2, 2)); cv::morphologyEx(image, image, cv::MORPH_GRADIENT, element); cv::imshow("OutputImage", image); cv::waitKey(0); }
效果:
顶帽变换和低帽变换
顶帽(白顶帽变换):
处理过程:原图像减去开运算的过程。功能:顶帽变换用于校正不均匀关照的影响(补充:均匀光照在从背景中提取目标的处理中扮演核心的角色)。
使用实例:
#include<opencv2/opencv.hpp> void main() { cv::Mat image = cv::imread("Fig0926(a)(rice).tif"); cv::namedWindow("SourceImage"); cv::namedWindow("OutputImage"); cv::imshow("SourceImage", image); //形态学梯度(MORPH_GRADIENT) cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)); cv::morphologyEx(image, image, cv::MORPH_TOPHAT, element); cv::imshow("OutputImage", image); cv::waitKey(0); }
效果展示:
低帽(黑底帽变换):
处理过程:闭运算减去原图像的过程。功能:突出比原图轮廓周围更暗的区域。
使用实例:
#include<opencv2/opencv.hpp> void main() { cv::Mat image = cv::imread("Fig0926(a)(rice).tif"); cv::namedWindow("SourceImage"); cv::namedWindow("OutputImage"); cv::imshow("SourceImage", image); //形态学梯度(MORPH_GRADIENT) cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10)); cv::morphologyEx(image, image, cv::MORPH_BLACKHAT, element); cv::imshow("OutputImage", image); cv::waitKey(0); }
效果图:
核心函数morphologyEx()介绍:
源码解析:
查看一下morphologyEx源代码:void cv::gpu::morphologyEx(const GpuMat& src, GpuMat& dst, int op, const Mat& kernel, GpuMat& buf1, GpuMat& buf2, Point anchor, int iterations, Stream& stream) { switch( op ) { case MORPH_ERODE: erode(src, dst, kernel, buf1, anchor, iterations, stream); break; case MORPH_DILATE: dilate(src, dst, kernel, buf1, anchor, iterations, stream); break; case MORPH_OPEN: erode(src, buf2, kernel, buf1, anchor, iterations, stream); dilate(buf2, dst, kernel, buf1, anchor, iterations, stream); break; case CV_MOP_CLOSE: dilate(src, buf2, kernel, buf1, anchor, iterations, stream); erode(buf2, dst, kernel, buf1, anchor, iterations, stream); break; case CV_MOP_GRADIENT: erode(src, buf2, kernel, buf1, anchor, iterations, stream); dilate(src, dst, kernel, buf1, anchor, iterations, stream); subtract(dst, buf2, dst, GpuMat(), -1, stream); break; case CV_MOP_TOPHAT: erode(src, dst, kernel, buf1, anchor, iterations, stream); dilate(dst, buf2, kernel, buf1, anchor, iterations, stream); subtract(src, buf2, dst, GpuMat(), -1, stream); break; case CV_MOP_BLACKHAT: dilate(src, dst, kernel, buf1, anchor, iterations, stream); erode(dst, buf2, kernel, buf1, anchor, iterations, stream); subtract(buf2, src, dst, GpuMat(), -1, stream); break; default: CV_Error(CV_StsBadArg, "unknown morphological operation"); } }
可以发现,这个函数使用了一个大的switch实现了多种形态学滤波的调用。
函数API介绍:
C++: void morphologyEx( InputArray src, OutputArray dst, int op, InputArraykernel, Pointanchor=Point(-1,-1), intiterations=1, intborderType=BORDER_CONSTANT, constScalar& borderValue=morphologyDefaultBorderValue() );
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像位深应该为以下五种之一:CV_8U,
CV_16U,CV_16S, CV_32F 或CV_64F。
第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
第三个参数,int类型的op,表示形态学运算的类型,可以是如下之一的标识符:
MORPH_OPEN – 开运算(Opening operation)
MORPH_CLOSE – 闭运算(Closing operation)
MORPH_GRADIENT -形态学梯度(Morphological gradient)
MORPH_TOPHAT - “顶帽”(“Top hat”)
MORPH_BLACKHAT - “黑帽”(“Black hat“)
另有CV版本的标识符也可选择,如CV_MOP_CLOSE,CV_MOP_GRADIENT,CV_MOP_TOPHAT,CV_MOP_BLACKHAT,这应该是OpenCV1.0系列版本遗留下来的标识符,和上面的“MORPH_OPEN”一样的效果。
第四个参数,InputArray类型的kernel,形态学运算的内核。若为NULL时,表示的是使用参考点位于中心3x3的核。我们一般使用函数getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
第五个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。
第六个参数,int类型的iterations,迭代使用函数的次数,默认值为1。
第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_ CONSTANT。
第八个参数,const
Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。
相关文章推荐
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- OpenCV 2.4.3 C++ 平滑处理分析
- 利用Python和OpenCV库将URL转换为OpenCV格式的方法
- python结合opencv实现人脸检测与跟踪
- 在树莓派2或树莓派B+上安装Python和OpenCV的教程
- opencv-python学习一--人脸检测
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- OpenCV配置,从来没有这么简单!
- ubuntu下opencv和qt的安装配置
- OpenCV学习笔记(二十五)——OpenCV图形界面设计Qt+VS2008
- 分享一些OpenCV实现立体视觉的经验
- 关于OpenCv图像变换与基本图形检测
- "应用程序正常初始化失败"-0xc0150002 解决办法
- OpenCV->HSV色彩空间
- opencv 内存泄露
- OpenCV函数cvFindContours
- OpenCV 2.3.1图像文件的读入和显示
- opencv2 矩阵方式 resize图像缩放代码