OpenCV图像腐蚀原理与API详解

星野
星野
发布时间:2026-10-15| 5人浏览过
原创

本文详解OpenCV中图像腐蚀的原理,介绍结构元素的定义与生成方法,深入解析erode函数的各项参数,包括src、dst、kernel、iterations等,并通过代码示例展示腐蚀操作对图像轮廓的影响及实际应用。

图像腐蚀过程类似于卷积操作,均依赖模板矩阵(即结构元素)来控制运算结果。在形态学操作中,结构元素的中心点可任意指定,其尺寸和内容也可根据需求自定义。定义好结构元素后,将其中心点依次遍历图像中所有非0像素。若结构元素覆盖的所有图像像素值均非0,则保留中心点对应的像素;否则,删除该像素。如图6-12所示,左侧为原图,中间为结构元素。当结构元素中心与像素A重合时,因其左侧和上方覆盖的像素值为0,故A被删除;当中心与像素B重合时,因所有覆盖像素值均为1,故B被保留。遍历所有像素后,得到右侧所示的腐蚀结果图。

图像腐蚀运算可用符号“Θ”表示,其数学表达式如式(6.4)所示。该公式表明,对图像A进行腐蚀运算,本质上是寻找那些能够被结构元素B完全包含的像素点。

生成常用的矩形、十字形及椭圆形结构元素的方法如下:


Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
  • shape:指定结构元素的类型,可选参数及其含义详见表6-5。
  • ksize:定义结构元素的尺寸大小。
  • anchor:指定结构元素中心点的位置,默认值为结构元素的几何中心。

该函数用于生成图像形态学操作中常用的矩形、十字形和椭圆形结构元素。第一个参数指定结构元素类型(可选参数及含义见相关表格),第二个参数指定结构元素尺寸,尺寸大小直接影响腐蚀效果:在类型相同的情况下,结构元素越大,腐蚀效果越显著。最后一个参数指定结构元素的中心点位置;对于十字形结构元素,中心点位置会影响腐蚀后的轮廓形状;而对于其他类型的结构元素,中心点位置仅影响形态学操作结果的平移量。

腐蚀函数


void erode( InputArray src, OutputArray dst, 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:腐蚀后的输出图像,其尺寸和数据类型与输入图像src保持一致。
  • kernel:用于腐蚀操作的结构元素,可自定义或通过getStructuringElement()函数生成。
  • anchor:结构元素中心点的位置,默认值为结构元素的几何中心点。
  • iterations:腐蚀进行的次数,默认值为1。
  • borderType:像素外推法的选择标志,取值范围见表3-5。默认参数为BORDER_DEFAULT,表示不包含边界值的倒序填充。
  • borderValue:在使用边界不变外推法时指定的边界值。

该函数依据结构元素对输入图像执行腐蚀操作,处理多通道图像时,每个通道独立进行腐蚀运算。函数第一个参数为待腐蚀图像,通道数任意,但数据类型须为CV_8U、CV_16U、CV_16S、CV_32F或CV_64F之一。第二个参数为输出图像,尺寸和数据类型与输入一致。第三和第四个参数涉及结构元素:第三个参数为结构元素本身,第四个参数为结构元素的中心位置,默认值为Point(-1,-1),即几何中心。第五个参数指定腐蚀次数,默认值为1,表示仅腐蚀一次;次数越多,效果越明显。第六个参数为像素外推法标志,第七个参数为边界不变外推法时的边界值。后两个参数对图像主体部分的腐蚀影响较小,通常使用默认值即可。

需注意,该函数的腐蚀过程仅针对图像中的非0像素。若图像以0像素为背景,腐蚀后图像内容会变得更细、更小;若以255像素为背景,腐蚀后图像内容会变得更粗、更大。

简单示例


//
// Created by smallflyfly on 2021/6/18.
//
 
#include "opencv2/opencv.hpp"
 
#include <iostream>
 
using namespace std;
using namespace cv;
 
 
void drawResult(Mat im, int num, Mat stats, Mat centroids, const string& name) {
    for (int i = 1; i < num; ++i) {
        int x = centroids.at<double>(i, 0);
        int y = centroids.at<double>(i, 1);
        cout << x << " " << y << endl;
        circle(im, Point(x, y), 2, Scalar(0, 0, 255), -1);
        int xmin = stats.at<int>(i, CC_STAT_LEFT);
        int ymin = stats.at<int>(i, CC_STAT_TOP);
        int w = stats.at<int>(i, CC_STAT_WIDTH);
        int h = stats.at<int>(i, CC_STAT_HEIGHT);
 
        Rect rect(xmin, ymin, w, h);
        rectangle(im, rect, Scalar(255, 255, 255), 2);
        putText(im, to_string(i), Point(x+5, y), FONT_HERSHEY_SCRIPT_SIMPLEX, 0.3, Scalar(0, 0, 255), 1);
    }
    imshow(name, im);
}
 
 
int main() {
 
    Mat src = (
                Mat_<uchar>(6, 6) <<
                        0, 0, 0, 0, 255, 0,
                        0, 255, 255, 255, 255, 255,
                        0, 255, 255, 255, 255, 0,
                        0, 255, 255, 255, 255, 0,
                        0, 255, 255, 255, 255, 0,
                        0, 0, 0, 0, 255, 0
            );
    resize(src, src, Size(0, 0), 50, 50, INTER_NEAREST);
    Mat m1, m2;
    m1 = getStructuringElement(0, Size(3, 3));
    m2 = getStructuringElement(1, Size(3, 3));
 
    Mat erodeM1, erodeM2;
    erode(src, erodeM1, m1, Point(-1, -1), 10);
    erode(src, erodeM2, m2, Point(-1, -1), 10);
 
    imshow("src", src);
    imshow("erodeM1", erodeM1);
    imshow("erodeM2", erodeM2);
 
    Mat xbim = imread("xiaobai.jpg");
    Mat xbM1, xbM2;
    erode(xbim, xbM1, m1, Point(-1, -1), 2);
    erode(xbim, xbM2, m2, Point(-1, -1), 2);
 
    imshow("xb", xbim);
    imshow("xbM1", xbM1);
    imshow("xbM2", xbM2);
 
    Mat im = imread("rice.jfif");
    Mat im1 = im.clone();
    Mat im2 = im.clone();
    Mat im3 = im.clone();
 
    Mat gray;
    cvtColor(im, gray, CV_BGR2GRAY);
    Mat riceBin;
    threshold(gray, riceBin, 125, 255, THRESH_BINARY);
 
    Mat out, stats, centroids;
    int count1 = connectedComponentsWithStats(riceBin, out, stats, centroids, 8, CV_16U);
    drawResult(im1, count1, stats, centroids, "no erode");
 
    Mat erodeIm1, erodeIm2;
    erode(riceBin, erodeIm1, m1, Point(-1, -1), 5);
    erode(riceBin, erodeIm2, m2, Point(-1, -1), 5);
 
    int count2 = connectedComponentsWithStats(erodeIm1, out, stats, centroids, 8, CV_16U);
    drawResult(erodeIm1, count2, stats, centroids, "erode1");
    int count3 = connectedComponentsWithStats(erodeIm2, out, stats, centroids, 8, CV_16U);
    drawResult(erodeIm2, count3, stats, centroids, "erode2");
 
    waitKey(0);
    destroyAllWindows();
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。