基于OpenCvSharp的数字图像处理 - 形态学

创建项目  |  文件与显示  |  像素操作  |  图像彩色类型转换  |  模糊、平滑、去噪  |  锐化、边缘检测  |  二值化  |  形态学  |  位置变换  |  直方图  |  霍夫变换  |  图像优化  |  图像分割

完整示例项目

 

一、腐蚀

形态学的内部算法依然是卷积,跟中值滤波一样,非线性。中值滤波取核范围的中位数,而腐蚀取最小值,膨胀取最大值。

腐蚀看起来的效果是亮的区域被侵蚀,可用于一些噪声的去除。

Mat src = new Mat(img_region, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.Erode(src, result, element);
result.SaveImage(img_result);

效果如下:

二、膨胀

膨胀的效果跟腐蚀相反,亮区会向外延伸,可用于填补孔洞。

Mat src = new Mat(img_region, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.Dilate(src, result, element);
result.SaveImage(img_result);

效果如下:

三、开运算

开运算是先腐蚀,再膨胀,可用于分隔区域,用来计数。

Mat src = new Mat(img_region, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.MorphologyEx(src, result, MorphTypes.Open, element);
result.SaveImage(img_result);

效果如下:

四、闭运算

闭运算是先膨胀,再腐蚀,可用于在检测连通区域时减少噪声。

Mat src = new Mat(img_region, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.MorphologyEx(src, result, MorphTypes.Close, element);
result.SaveImage(img_result);

效果如下:

五、形态梯度

形态梯度是用膨胀结果减腐蚀结果,能够找出目标的骨架。

Mat src = new Mat(img_region, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.MorphologyEx(src, result, MorphTypes.Gradient, element);
result.SaveImage(img_result);

效果如下:

六、顶帽

顶帽是用源图减去开运算的结果,突出了图像中亮的部分。

Mat src = new Mat(img_cell, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(9, 9));
Cv2.MorphologyEx(src, result, MorphTypes.TopHat, element);
result.SaveImage(img_result);

效果如下:

七、黑帽

黑帽是用闭运算的结果减去原图,突出了图像中暗的部分。

Mat src = new Mat(img_cell, ImreadModes.Grayscale);
Mat result = new Mat();
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(9, 9));
Cv2.MorphologyEx(src, result, MorphTypes.BlackHat, element);
result.SaveImage(img_result);

效果如下:

 

八、连通区域

在进行一些形态学变换之后,我们可能希望找出二值图中的连通区域。例如在海域中的小岛,我们希望在每座岛上标上一个数字。

实现示例代码如下:

Mat src = new Mat(img_fish, ImreadModes.Grayscale);
Cv2.Blur(src, src, new OpenCvSharp.Size(3, 3));

Mat r1 = src.Threshold(240, 255, ThresholdTypes.Binary);

Cv2.ConnectedComponents(r1, out int[,] labels, PixelConnectivity.Connectivity8);

Vec3b[] colors = new Vec3b[] {
    new Vec3b(255,0,0),
    new Vec3b(0,255,0),
    new Vec3b(0,0,255),
    new Vec3b(255,255,0),
    new Vec3b(255,0,255),
    new Vec3b(0,255,255),
    new Vec3b(180,120,0),
    new Vec3b(0,120,180),
    new Vec3b(120,0,180)
};

Mat r2 = new Mat(src.Rows, src.Cols, MatType.CV_8UC3);
for (int i = 0; i < r2.Rows; i++)
{
    for (int j = 0; j < r2.Cols; j++)
    {
        r2.Set<Vec3b>(i, j, colors[labels[i, j] % 9]);
    }
}

r2.SaveImage(img_result);

效果如下:

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值