opencv学习笔记——形态学滤波

开运算
功能:用于消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积,同时抑制比结构元小的亮细节。
使用实例:

#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);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

效果图如下:
这里写图片描述


闭运算

处理过程:先膨胀后腐蚀
功能:用来填充物体内细小空洞、连接邻近物体、平滑其边界的同时并不明显改变其面积,同时抑制比结构元小的暗细节。
使用实例:

#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);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

效果:
这里写图片描述

形态学梯度

处理过程:膨胀图和腐蚀图相减
功能:对二值化图像进行这一操作可以将边缘突出来,可以使用形态学梯度来保留物体的边缘轮廓
使用实例:

#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);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

效果:
这里写图片描述

顶帽变换和低帽变换

顶帽(白顶帽变换):

处理过程:原图像减去开运算的过程。
功能:顶帽变换用于校正不均匀关照的影响(补充:均匀光照在从背景中提取目标的处理中扮演核心的角色)。
使用实例:

#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);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

效果展示:
这里写图片描述


低帽(黑底帽变换):

处理过程:闭运算减去原图像的过程。
功能:突出比原图轮廓周围更暗的区域。
使用实例:

#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);
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

效果图:
这里写图片描述


核心函数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");
    }
}

 
 
  • 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

可以发现,这个函数使用了一个大的switch实现了多种形态学滤波的调用。

函数API介绍:

C++: void morphologyEx(  
InputArray src,  
OutputArray dst,  
int op,  
InputArraykernel,  
Pointanchor=Point(-1,-1),  
intiterations=1,  
intborderType=BORDER_CONSTANT,  
constScalar& borderValue=morphologyDefaultBorderValue() );  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 第一个参数,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()函数得到更详细的解释。

这里写链接内容

在C#中,使用OpenCVSharp库进行图像处理,特别是灰度形态学滤波(Grayscale Morphological Filtering)是非常常见的。形态学滤波主要用于去除噪声、连接断裂的线条或填充孔洞等,通常分为两个主要步骤:结构元素和操作。 1. **结构元素**:这是形态学操作的基础,通常是像矩形、十字或椭圆这样的简单形状,但也可以自定义。OpenCVSharp提供了一些预定义的结构元素类型,如`MorphologyExStructuringElement.ElementShape.Rect`或`MorphologyExStructuringElement.ElementShape.Ellipse`。 2. **基本操作**: - **腐蚀(Erosion)**:通过将结构元素在图像上滑动并移除每个位置与结构元素中心点相交区域的像素值,从而缩小物体边缘。 - **膨胀(Dilation)**:相反的过程,结构元素填充像素使得边缘向外扩展。 - **开运算(Opening)**:先腐蚀后膨胀,用于去除小的噪声点。 - **闭运算(Closing)**:先膨胀后腐蚀,常用于填补小的空洞。 - **顶帽(Top Hat)**:原图减去腐蚀的结果,突出高亮细节。 - **黑帽(Black Hat)**:腐蚀后的图像减去原图,突出低对比度区域。 3. **形态学链**:有时候可能需要执行一系列连续的形态学操作,比如先用开运算消除噪声,然后用闭运算恢复边缘完整性。 在实际代码中,你可以这样使用: ```csharp using Emgu.CV; using Emgu.CV.Structure; // 加载图片 Image<Gray, byte> src = new Image<Gray, byte>("path_to_your_image.jpg"); // 定义结构元素 Mat kernel = MatOfByte.Create(3, 3, (byte[,])new[,] { {0, 1, 0}, {1, 1, 1}, {0, 1, 0} }); // 矩形结构 // 应用腐蚀操作 Image<Gray, byte> erosion = src.MorphologyEx(kernel, Emgu.CV.CvEnum.MORPHOPS.CV_ERODE); // 类似地,为其他操作替换参数 var dilationKernel = ...; // 填充空洞 erosion = erosion.MorphologyEx(dilationKernel, Emgu.CV.CvEnum.MORPHOPS.CV_DILATE); ``` 如果你想要了解更多关于OpenCVSharp在C#中的应用,相关问题可以包括:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值