形态学操作篇 原理公式代码齐活

发布于:2024-11-03 ⋅ 阅读:(42) ⋅ 点赞:(0)

一、腐蚀

腐蚀操作的核心原理是利用一个结构元素在图像上进行扫描,判断结构元素所覆盖的区域与前景像素的关系。如果结构元素完全被包含在前景像素区域内,那么结构元素中心对应的像素位置在腐蚀后的图像中被标记为前景像素;如果结构元素不完全被包含在前景像素区域内,那么中心像素位置被标记为背景像素。

腐蚀操作的数学表达式为:

E(A,B) = A ⊖ B = {z | (B)z ⊆ A}

其中:A 是被处理的图像,B 是结构元素,(B)z 表示 B 平移到点 z。

腐蚀操作的效果是缩小图像中的明亮区域(前景),扩大暗区域(背景)。

例如,假设有一个简单的二值图像,其中前景像素为白色(值为 1),背景像素为黑色(值为 0)。结构元素是一个 3x3 的矩阵,全为 1。当这个结构元素在图像上移动时,如果它所覆盖的 9 个像素位置全部为白色,那么在腐蚀后的图像中,对应结构元素中心位置的像素也为白色;如果结构元素覆盖的区域内有一个或多个像素为黑色,那么中心位置像素在腐蚀后的图像中被置为黑色。

二、膨胀

膨胀操作的原理是当结构元素与前景像素有交集时,将结构元素中心对应的像素标记为前景像素。

同样以二值图像为例,结构元素在图像上移动,只要结构元素覆盖的区域内有一个像素为白色,那么在膨胀后的图像中,对应结构元素中心位置的像素就被置为白色;只有当结构元素覆盖的区域全部为黑色像素时,中心位置像素在膨胀后的图像中才被置为黑色。

膨胀操作的数学表达式为:

D(A,B) = A ⊕ B = {z | (B̂)z ∩ A ≠ ∅}

其中:A 是被处理的图像,B 是结构元素,B̂ 是 B 的反射,(B̂)z 表示 B̂ 平移到点 z。

三、开运算

开运算先进行腐蚀操作,再进行膨胀操作。腐蚀操作可以去除图像中的小物体和细小的突出部分,使物体的轮廓变得更加平滑。然后进行膨胀操作,能够在一定程度上恢复物体的大小和形状,但不会恢复被腐蚀掉的较大物体。

例如,对于一个有噪声和小突起的图像,开运算首先通过腐蚀去除小突起和噪声点,然后通过膨胀稍微恢复物体的形状,使得图像更加干净、平滑。

开运算是一种先腐蚀后膨胀的运算,可以表示为:
eq?A%20%5Ccirc%20B%20%3D%20%28A%20%5Cominus%20B%29%20%5Coplus%20B
其中:

  • (A) 是输入图像,
  • (B) 是结构元素,
  • (\ominus) 表示腐蚀运算,
  • (\oplus) 表示膨胀运算.

在实际应用中,开运算常用于去除小的噪声

具体来说:

在原图中,你可能会看到一些孤立的亮点噪声,物体的轮廓不够平滑,可能有一些细小的毛刺。

经过开运算后,首先腐蚀操作会去除那些孤立的噪声点和小的突出部分,使物体的轮廓变得更加平滑。然后膨胀操作会在一定程度上恢复物体的大小和形状,但不会恢复那些被腐蚀掉的较大噪声物体。此时,图像中的噪声大大减少,物体的轮廓更加规整,看起来更加清晰和干净。

例如,原图中有一个圆形物体,其边缘有一些小的凸起和一些孤立的噪声点。经过开运算后,圆形物体的边缘变得更加光滑,那些小的凸起被去除,孤立的噪声点也消失了,整个图像更加美观和易于分析。

8574fee0b1bf43c2be20896a2117578c.png9cfbd1622c32437eaa4f24bdb11e909d.png

四、闭运算

闭运算先进行膨胀操作,再进行腐蚀操作。膨胀操作可以填充物体内部的小孔洞和连接邻近的物体,使物体的轮廓更加完整。接着进行腐蚀操作,能够去除因膨胀而产生的一些不必要的连接和突出部分,同时保持物体的基本形状和大小。

比如,对于一个有缝隙的图像,闭运算首先通过膨胀填充缝隙,然后通过腐蚀去除多余的连接部分,使物体更加规整。

闭运算是一种先膨胀后腐蚀的运算,可以表示为:
eq?A%20%5Cbullet%20B%20%3D%20%28A%20%5Coplus%20B%29%20%5Cominus%20B
其中的符号与上面类似。

在实际应用中,闭运算则用于填充小孔或连接近邻的对象

38a85d26b5074ad5bd431a10bdb6ef22.pngc133e7c7406f41b1bbceb2f5bae94766.png

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    // 读取图像
    Mat image = imread("your_image.jpg", IMREAD_GRAYSCALE);

    if (image.empty()) {
        cout << "无法读取图像" << endl;
        return -1;
    }

    // 创建结构元素(这里使用 5x5 的矩形结构元素)
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));

    // 开运算
    Mat openImage;
    morphologyEx(image, openImage, MORPH_OPEN, kernel);

    // 闭运算
    Mat closeImage;
    morphologyEx(image, closeImage, MORPH_CLOSE, kernel);

    // 显示原图、开运算结果和闭运算结果
    imshow("原图", image);
    imshow("开运算结果", openImage);
    imshow("闭运算结果", closeImage);

    waitKey(0);
    return 0;
}

五、形态学梯度

形态学梯度是通过膨胀后的图像减去腐蚀后的图像得到的。膨胀操作会使物体的边界向外扩张,腐蚀操作会使物体的边界向内收缩。两者相减后,得到的结果突出了物体的边缘部分,即物体的轮廓信息。

例如,对于一个具有明显边界的物体图像,形态学梯度操作可以清晰地显示出物体的边缘,增强图像中物体与背景的对比度。

一、顶帽运算和底帽运算的原理

(一)顶帽运算

  1. 定义
    • 顶帽运算(Top-hat transform)又称为礼帽变换,是原图像与开运算结果图像的差值。它能够提取出图像中的明亮细节和孤立的亮点,突出图像中的局部明亮区域。
  2. 数学表达式
    • 设原始图像为I,结构元素为B,则顶帽运算T可表示为:T = I - opening(I, B),其中opening(I, B)表示对图像I进行以B为结构元素的开运算。
  3. 原理分析
    • 开运算具有去除图像中较小明亮区域和孤立亮点、平滑物体轮廓的作用。当用原始图像减去开运算的结果时,就得到了那些被开运算去除的部分,也就是图像中的明亮细节和孤立的亮点。
    • 例如,对于一个含有明亮噪声点的图像,开运算会去除这些噪声点。而顶帽运算则能够将这些被去除的噪声点提取出来,作为顶帽运算的结果。
    • 39509331045e406abdaafedd41da2dcb.png56f79b8790e54b8eafd50238c9850aee.png

(二)底帽运算

  1. 定义
    • 底帽运算(Bottom-hat transform)又称为黑帽变换,是闭运算结果图像与原图像的差值。它能够提取出图像中的黑暗细节和孤立的暗点,突出图像中的局部黑暗区域。
  2. 数学表达式
    • 设原始图像为I,结构元素为B,则底帽运算B可表示为:B = closing(I, B) - I,其中closing(I, B)表示对图像I进行以B为结构元素的闭运算。
  3. 原理分析
    • 闭运算具有填充图像中较小黑暗区域和连接邻近物体、平滑物体轮廓的作用。当用闭运算的结果减去原始图像时,就得到了那些被闭运算填充或改变的部分,也就是图像中的黑暗细节和孤立的暗点。
    • 例如,对于一个含有黑暗噪声点的图像,闭运算会填充这些噪声点。而底帽运算则能够将这些被填充的噪声点提取出来,作为底帽运算的结果。

953c4bcf0fa14b939798686bf6aad73f.png

二、顶帽运算和底帽运算的应用场景

(一)医学图像处理

  1. 细胞检测
    • 在医学显微镜图像中,细胞通常呈现出不同的亮度和形态。顶帽运算可以用于突出图像中的明亮细胞,帮助医生或研究人员更准确地检测和分析细胞的数量、形状和分布。
    • 例如,在血液细胞图像中,红细胞通常比较暗淡,而白细胞则相对较亮。通过顶帽运算,可以突出白细胞的区域,方便后续的细胞分类和计数。
  2. 病变检测
    • 对于医学影像中的病变区域,如肿瘤、炎症等,往往会表现出与周围组织不同的亮度或对比度。底帽运算可以用于突出图像中的黑暗病变区域,辅助医生进行病变的检测和诊断。
    • 例如,在脑部磁共振图像中,肿瘤区域可能会呈现出较低的亮度。通过底帽运算,可以将这些黑暗区域提取出来,帮助医生更准确地定位和评估肿瘤的大小和位置。

(二)工业检测

  1. 表面缺陷检测
    • 在工业生产中,产品表面的缺陷可能会表现为明亮的划痕、污点或黑暗的凹坑、裂缝等。顶帽运算和底帽运算可以分别用于检测图像中的明亮缺陷和黑暗缺陷。
    • 例如,对于金属表面的划痕检测,可以使用顶帽运算突出明亮的划痕区域。对于塑料零件表面的凹坑检测,可以使用底帽运算突出黑暗的凹坑区域。
  2. 印刷电路板检测
    • 在印刷电路板(PCB)的制造过程中,需要对电路板上的焊点、线路等进行检测,以确保产品质量。顶帽运算和底帽运算可以用于检测 PCB 图像中的缺陷,如短路、断路、焊锡过多或过少等。
    • 例如,对于短路检测,可以使用顶帽运算突出由于焊锡过多而导致的明亮连接区域。对于断路检测,可以使用底帽运算突出由于线路断开而导致的黑暗区域。

(三)文档图像处理

  1. 文字增强
    • 在扫描或拍照得到的文档图像中,文字可能会受到光照不均匀、背景噪声等因素的影响,导致文字的清晰度和对比度下降。顶帽运算可以用于增强图像中的明亮文字区域,提高文字的可读性。
    • 例如,对于一份手写文档图像,由于纸张的颜色和纹理不同,文字可能会显得比较暗淡。通过顶帽运算,可以突出文字的明亮部分,使文字更加清晰可辨。
  2. 背景去除
    • 在文档图像处理中,有时需要去除背景图案或水印,以便更好地提取文字信息。底帽运算可以用于去除图像中的黑暗背景区域,使文字更加突出。
    • 例如,对于一份带有水印的文档图像,水印通常会呈现出较低的亮度。通过底帽运算,可以将水印区域提取出来,然后通过图像减法去除水印,得到干净的文字图像。

(四)天文学图像处理

  1. 恒星检测
    • 在天文学图像中,恒星通常表现为明亮的点源。顶帽运算可以用于突出图像中的恒星区域,帮助天文学家更准确地检测和分析恒星的位置、亮度和分布。
    • 例如,在星空图像中,恒星的亮度可能会受到大气湍流、背景噪声等因素的影响。通过顶帽运算,可以去除背景噪声,突出恒星的明亮区域,方便后续的恒星识别和分类。
  2. 星系结构分析
    • 对于星系图像,底帽运算可以用于突出图像中的黑暗尘埃带和星际介质区域,帮助天文学家更好地了解星系的结构和演化。
    • 例如,在星系图像中,尘埃带通常会呈现出较低的亮度。通过底帽运算,可以将这些黑暗区域提取出来,与星系的明亮区域进行对比,从而更好地分析星系的形态和结构。

(五)安全监控领域

  1. 异常行为检测
    • 在安全监控视频中,异常行为通常会表现为突然出现的明亮或黑暗区域。顶帽运算和底帽运算可以用于检测图像中的这些异常区域,帮助监控人员及时发现潜在的安全隐患。
    • 例如,在一个商场的监控视频中,如果有人突然扔出一个明亮的物体,顶帽运算可以快速检测到这个明亮区域的变化,从而触发报警系统。同样,如果有人在黑暗的角落里进行可疑活动,底帽运算可以突出这个黑暗区域,引起监控人员的注意。
  2. 人脸识别
    • 在人脸识别系统中,顶帽运算和底帽运算可以用于增强人脸图像的对比度和细节,提高人脸识别的准确率。
    • 例如,对于一个低对比度的人脸图像,顶帽运算可以突出人脸的明亮部分,如眼睛、嘴巴等,底帽运算可以突出人脸的黑暗部分,如眉毛、鼻孔等。通过对这些区域的增强,可以使人脸的特征更加明显,有利于人脸识别算法的准确识别。

在我看来,顶帽运算和底帽运算作为形态学图像处理的重要工具,在医学、工业、文档处理、天文学和安全监控等领域都有着广泛的应用。通过突出图像中的明亮或黑暗细节,它们可以帮助我们更好地分析和处理图像,提高图像的质量和可读性,为各种实际应用提供有力的支持。

 

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    // 读取图像
    Mat image = imread("your_image.jpg", IMREAD_GRAYSCALE);

    if (image.empty()) {
        cout << "无法读取图像" << endl;
        return -1;
    }

    // 创建结构元素(这里使用 5x5 的矩形结构元素)
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));

    // 开运算
    Mat openImage;
    morphologyEx(image, openImage, MORPH_OPEN, kernel);

    // 闭运算
    Mat closeImage;
    morphologyEx(image, closeImage, MORPH_CLOSE, kernel);

    // 顶帽运算
    Mat topHatImage;
    subtract(image, openImage, topHatImage);

    // 底帽运算
    Mat bottomHatImage;
    subtract(closeImage, image, bottomHatImage);

    // 显示原图、顶帽运算结果和底帽运算结果
    imshow("原图", image);
    imshow("顶帽运算结果", topHatImage);
    imshow("底帽运算结果", bottomHatImage);

    waitKey(0);
    return 0;
}

代码都能直接复制使用,创作不易,希望大家点个关注不迷路~每天都会有算法内容更新哦。

 

 


网站公告

今日签到

点亮在社区的每一天
去签到