c++视觉处理-----膨胀腐蚀

news2024/9/22 1:12:44

c++视觉处理膨胀腐蚀

膨胀腐蚀的区别

膨胀(Dilation)和腐蚀(Erosion)是形态学图像处理中的两种基本操作,它们有不同的效果和应用:

  1. 膨胀(Dilation):

    • 膨胀操作用于增加物体的尺寸,使物体变大。
    • 它通过将每个像素替换为其邻域内的最大值来实现。
    • 膨胀通常用于连接分离的物体、填充空洞、增加物体的面积,以及提取物体的外部轮廓。
    • 在二值图像中,膨胀可以用于扩展白色物体(前景)的区域,通常与其他形态学操作(如开运算或闭运算)一起使用。
  2. 腐蚀(Erosion):

    • 腐蚀操作用于减小物体的尺寸,使物体变小。
    • 它通过将每个像素替换为其邻域内的最小值来实现。
    • 腐蚀通常用于分离接触的物体、去除小的噪点、缩小物体的面积,以及提取物体的内部结构。
    • 在二值图像中,腐蚀可以用于缩小白色物体(前景)的区域。

总结来说,膨胀使物体变大,而腐蚀使物体变小。这两种操作通常在形态学图像处理中配合使用,以实现不同的图像增强、分割和去噪等应用。同时,它们也是其他复杂形态学操作(如开运算和闭运算)的基本构建块。

膨胀:cv::dilate()

cv::dilate() 是OpenCV中的一个图像形态学操作函数,用于执行图像的膨胀操作。膨胀是形态学处理中的一种操作,它可以用来增强二值图像中的目标区域。膨胀操作通过将目标区域扩展,可以填充空洞、连接断裂的区域以及增加目标的尺寸。

下面是 cv::dilate() 函数的基本语法:

void cv::dilate(
    cv::InputArray src,          // 输入图像
    cv::OutputArray dst,         // 输出图像
    cv::InputArray kernel,       // 膨胀核
    cv::Point anchor = cv::Point(-1,-1),
    int iterations = 1,
    int borderType = cv::BORDER_CONSTANT,
    const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);

参数解释:

  • src:输入图像。
  • dst:输出图像,将膨胀后的图像存储在这里。
  • kernel:膨胀核,它定义了膨胀操作的形状和大小。通常使用 cv::getStructuringElement() 来创建膨胀核。
  • anchor:锚点位置,指示膨胀核的中心。默认值为 (-1, -1),表示核的中心。
  • iterations:膨胀操作的迭代次数。默认值为 1。
  • borderType:边界处理方式,用于处理边界像素。默认值为 cv::BORDER_CONSTANT
  • borderValue:在边界处理方式为 cv::BORDER_CONSTANT 时使用的边界像素值。默认值为 cv::morphologyDefaultBorderValue()

膨胀操作的基本思想是将核在图像上滑动,如果核覆盖区域内的任何像素值为非零(白色),则将目标像素置为白色。这导致了目标区域的扩张。

创建形态学操作的结构元素:cv::getStructuringElement()

cv::getStructuringElement() 是OpenCV中的一个函数,用于创建形态学操作的结构元素(structuring element)。形态学操作(如腐蚀、膨胀、开运算、闭运算等)通常需要一个结构元素,该元素定义了操作的形状和大小。cv::getStructuringElement() 函数用于创建这样的结构元素。

以下是 cv::getStructuringElement() 函数的基本语法:

cv::Mat cv::getStructuringElement(
    int shape,          // 结构元素的形状,如 cv::MORPH_RECT、cv::MORPH_ELLIPSE、cv::MORPH_CROSS 等
    cv::Size ksize,     // 结构元素的大小,通常是一个奇数大小的矩阵
    cv::Point anchor = cv::Point(-1,-1)
);

参数解释:

  • shape:结构元素的形状,可以是以下常量之一:
    • cv::MORPH_RECT:矩形结构元素。
    • cv::MORPH_ELLIPSE:椭圆结构元素。
    • cv::MORPH_CROSS:十字形结构元素。
  • ksize:结构元素的大小,通常是一个奇数大小的矩阵,表示结构元素的宽度和高度。
  • anchor:锚点位置,通常为 (-1, -1),表示结构元素的中心。

cv::getStructuringElement() 函数返回一个 cv::Mat 对象,表示所创建的结构元素。

以下是一个示例,演示如何使用 cv::getStructuringElement() 创建不同形状的结构元素:

#include <opencv2/opencv.hpp>

int main() {
    // 创建矩形结构元素
    cv::Mat rectangularElement = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));

    // 创建椭圆形结构元素
    cv::Mat ellipticalElement = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));

    // 创建十字形结构元素
    cv::Mat crossElement = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5, 5));

    // 显示创建的结构元素
    cv::imshow("Rectangular Element", rectangularElement);
    cv::imshow("Elliptical Element", ellipticalElement);
    cv::imshow("Cross Element", crossElement);

    cv::waitKey(0);

    return 0;
}

在这个示例中,我们创建了三种不同形状的结构元素:矩形、椭圆和十字形。您可以根据需要调整 cv::MORPH_RECTcv::MORPH_ELLIPSEcv::MORPH_CROSS 常量以选择不同的结构元素形状。这些结构元素通常用于形态学操作,例如腐蚀和膨胀。

使用cv::getStructuringElement() 3x3的矩形核再使用膨胀cv::dilate()操作

以下是一个示例,演示如何使用 cv::dilate() 函数对二值图像执行膨胀操作:

#include <opencv2/opencv.hpp>

int main() {
    // 读取输入二值图像
    cv::Mat binaryImage = cv::imread("binary_image.png", cv::IMREAD_GRAYSCALE);

    if (binaryImage.empty()) {
        std::cerr << "Failed to open the input image!" << std::endl;
        return -1;
    }

    // 定义膨胀核(3x3的矩形核)
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    // 执行膨胀操作
    cv::Mat dilatedImage;
    cv::dilate(binaryImage, dilatedImage, kernel);

    // 显示原始二值图像和膨胀后的图像
    cv::namedWindow("Binary Image", cv::WINDOW_NORMAL);
    cv::namedWindow("Dilated Image", cv::WINDOW_NORMAL);

    cv::imshow("Binary Image", binaryImage);
    cv::imshow("Dilated Image", dilatedImage);

    cv::waitKey(0);

    return 0;
}

在这个示例中,我们首先读取了一个二值图像,然后定义了一个膨胀核(3x3的矩形核)。接下来,我们使用 cv::dilate() 函数对输入的二值图像执行膨胀操作,并将结果存储在 dilatedImage 中。最后,我们显示了原始二值图像和膨胀后的图像。

在这里插入图片描述

腐蚀:cv::erode()

腐蚀是图像形态学处理中的一种基本操作,通常用于减小二值图像中的目标对象的尺寸。腐蚀操作通过在图像上滑动一个结构元素(通常是一个小的矩形或圆形核),将核中心与图像中的像素进行比较,如果核中的所有像素都与图像中的像素匹配(都是白色像素),则将中心像素保留为白色,否则将其置为黑色。

在OpenCV中,可以使用 cv::erode() 函数来执行腐蚀操作。

以下是 cv::erode() 函数的基本语法:

void cv::erode(
    cv::InputArray src,          // 输入图像
    cv::OutputArray dst,         // 输出图像
    cv::InputArray kernel,       // 结构元素核
    cv::Point anchor = cv::Point(-1,-1),
    int iterations = 1,
    int borderType = cv::BORDER_CONSTANT,
    const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);

参数解释:

  • src:输入图像,通常是一个二值图像。
  • dst:输出图像,将腐蚀后的图像存储在这里。
  • kernel:结构元素核,用于定义腐蚀操作的形状和大小。
  • anchor:锚点位置,指示结构元素核的中心。默认值为 (-1, -1),表示核的中心。
  • iterations:腐蚀操作的迭代次数。默认值为 1。
  • borderType:边界处理方式,用于处理边界像素。默认值为 cv::BORDER_CONSTANT
  • borderValue:在边界处理方式为 cv::BORDER_CONSTANT 时使用的边界像素值。默认值为 cv::morphologyDefaultBorderValue()

以下是一个示例,演示如何使用 cv::erode() 函数对二值图像执行腐蚀操作:

#include <opencv2/opencv.hpp>

int main() {
    // 读取输入二值图像
    cv::Mat binaryImage = cv::imread("binary_image.png", cv::IMREAD_GRAYSCALE);

    if (binaryImage.empty()) {
        std::cerr << "Failed to open the input image!" << std::endl;
        return -1;
    }

    // 定义腐蚀核(3x3的矩形核)
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    // 执行腐蚀操作
    cv::Mat erodedImage;
    cv::erode(binaryImage, erodedImage, kernel);

    // 显示原始二值图像和腐蚀后的图像
    cv::namedWindow("Binary Image", cv::WINDOW_NORMAL);
    cv::namedWindow("Eroded Image", cv::WINDOW_NORMAL);

    cv::imshow("Binary Image", binaryImage);
    cv::imshow("Eroded Image", erodedImage);

    cv::waitKey(0);

    return 0;
}

在这个示例中,我们首先读取了一个二值图像,然后定义了一个腐蚀核(3x3的矩形核)。接下来,我们使用 cv::erode() 函数对输入的二值图像执行腐蚀操作,并将结果存储在 erodedImage 中。最后,我们显示了原始二值图像和腐蚀后的图像。腐蚀操作通常用于去除小的噪点、分离接触的目标对象等。

在这里插入图片描述

使用本地相机实时膨胀处理

#include <opencv2/opencv.hpp>

// 全局变量,用于存储滑动条的值
int kernelSize = 1; // 初始核大小为1

// 回调函数,用于处理滑动条的值变化
void onTrackbar(int value, void* userdata) {
    cv::VideoCapture* cap = static_cast<cv::VideoCapture*>(userdata);

    // 创建窗口
    cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);

    while (true) {
        cv::Mat frame;

        // 从相机中读取一帧图像
        *cap >> frame;

        if (frame.empty()) {
            std::cerr << "Failed to read frame from the camera!" << std::endl;
            break;
        }

        // 定义膨胀核
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(kernelSize, kernelSize));

        // 创建一个膨胀后的图像副本
        cv::Mat dilatedFrame;

        // 使用膨胀操作处理图像
        cv::dilate(frame, dilatedFrame, kernel);

        // 显示实时摄像头图像和膨胀后的图像
        cv::imshow("Live Camera Feed", frame);
        cv::imshow("Dilated Frame", dilatedFrame);

        // 检查键盘输入,如果按下ESC键,退出循环
        char key = cv::waitKey(1);
        if (key == 27) // 27对应ESC键的ASCII码
            break;
    }
}

int main() {
    cv::VideoCapture cap(0);

    if (!cap.isOpened()) {
        std::cerr << "Could not open the camera!" << std::endl;
        return -1;
    }

    // 创建窗口
    cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);

    // 创建滑动条
    cv::createTrackbar("Kernel Size", "Live Camera Feed", &kernelSize, 30, onTrackbar, &cap);

    // 初始化一次滑动条回调函数以显示默认值
    onTrackbar(kernelSize, &cap);

    // 释放摄像头资源和关闭窗口
    cap.release();
    cv::destroyAllWindows();

    return 0;
}

使用本地相机实时腐蚀处理

#include <opencv2/opencv.hpp>

// 全局变量,用于存储滑动条的值
int kernelSize = 1; // 初始核大小为1

// 回调函数,用于处理滑动条的值变化
void onTrackbar(int value, void* userdata) {
    cv::VideoCapture* cap = static_cast<cv::VideoCapture*>(userdata);

    // 创建窗口
    cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);

    while (true) {
        cv::Mat frame;

        // 从相机中读取一帧图像
        *cap >> frame;

        if (frame.empty()) {
            std::cerr << "Failed to read frame from the camera!" << std::endl;
            break;
        }

        // 定义腐蚀核
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(kernelSize, kernelSize));

        // 创建一个腐蚀后的图像副本
        cv::Mat erodedFrame;

        // 使用腐蚀操作处理图像
        cv::erode(frame, erodedFrame, kernel);

        // 显示实时摄像头图像和腐蚀后的图像
        cv::imshow("Live Camera Feed", frame);
        cv::imshow("Eroded Frame", erodedFrame);

        // 检查键盘输入,如果按下ESC键,退出循环
        char key = cv::waitKey(1);
        if (key == 27) // 27对应ESC键的ASCII码
            break;
    }
}

int main() {
    cv::VideoCapture cap(0);

    if (!cap.isOpened()) {
        std::cerr << "Could not open the camera!" << std::endl;
        return -1;
    }

    // 创建窗口
    cv::namedWindow("Live Camera Feed", cv::WINDOW_NORMAL);

    // 创建滑动条
    cv::createTrackbar("Kernel Size", "Live Camera Feed", &kernelSize, 30, onTrackbar, &cap);

    // 初始化一次滑动条回调函数以显示默认值
    onTrackbar(kernelSize, &cap);

    // 释放摄像头资源和关闭窗口
    cap.release();
    cv::destroyAllWindows();

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1075738.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Compose加载本地图片和网络图片

加载本地图片 Image(modifier Modifier.fillMaxWidth().height(200.dp),painter painterResource(id R.drawable.img),contentDescription "描述",//0~1完全透明到完全不透明设置alpha 1f,//图片拉伸或裁剪设置contentScale ContentScale.Crop ) 加载本地图…

AntV G6 dom节点绑定事件问题

问题&#xff1a; graph.on("node:click"&#xff0c; e > {})监听不到dom节点里面对应事件 比如dom节点里面自定义按钮和输入框&#xff0c;需要监听按钮点击和输入框聚焦事件 效果如下&#xff1a; 对应代码&#xff1a; <template><div id"c…

数据结构:排序- 插入排序(插入排序and希尔排序) , 选择排序(选择排序and堆排序) , 交换排序(冒泡排序and快速排序) , 归并排序

目录 前言 复杂度总结 预备代码 插入排序 1.直接插入排序: 时间复杂度O(N^2) \空间复杂度O(1) 复杂度&#xff08;空间/时间&#xff09;&#xff1a; 2.希尔排序&#xff1a; 时间复杂度 O(N^1.3~ N^2&#xff09; 空间复杂度为O(1) 复杂度&#xff08;空间/时间&#…

WiFi标签注册流程

7.5寸桌牌&#xff1a;K: 注册键&#xff0c;R: 复位键 长按K键不动&#xff0c;绿灯长亮&#xff0c;再按一下R键&#xff0c;等待绿灯快闪后就可以松开按键&#xff0c;绿灯变慢闪&#xff0c;设备即可进入配置注册模式。 4.2寸标签&#xff1a;右键: 注册键&#xff0c;背后…

网络安全70部学员第二阶段项目验收顺利结束

网络安全70部的小伙伴 经过近三个月的学习 专业技能都有了质的飞跃 为了检验学员们的学习情况 同时巩固所学知识点&#xff0c;查漏补缺 近日&#xff0c;进行了网络阶段项目验收工作 项目背景&#xff1a;某公司由市场部、客服部、产品部、行政部、财务部、人事部以及总经…

GNOME 45 动态三层缓存补丁更新

导读GNOME 45 "Rīga" 上周已正式发布&#xff0c;此版本虽然有许多针对桌面环境的改进&#xff0c;但上游缺少的一个功能是 Canonical 主导的 Mutter 动态三层缓存。 动态三层缓存用于在需要时提升性能&#xff0c;并且已被证明有助于提高桌面渲染性能&#xff0c;…

10.selenium进阶

上述我们学习了selenium入门的一些操作, 本节知识点学习一些selenium的高级用法 1、嵌套网页 ​ 在前端开发中如果有这么一个需求。一个页面上的内容要被其它页面所共用。也就是说两个或者两个以上的页面需要共同存在与同一个页面。在前端页面开发中可以把写好的代码在每个页面…

HTML基础入门01

目录 1.HTML基础 1.1HTML标签 1.2HTML 文件基本结构 1.3标签层次结构 1.4快速生成代码框架 2.HTML 常见标签 2.1注释标签 2.2标题标签: h1-h6 2.3段落标签: p 2.4.换行标签: br 3.综合案例: 展示博客 1.HTML基础 1.1HTML标签 HTML 代码是由 "标签" 构成…

奥威BI系统:做数据可视化大屏,又快又简单

数据可视化大屏的制作难吗&#xff1f;会很花时间精力吗&#xff1f;这就要看用的是什么软件了。如果用的是BI系统&#xff0c;特别是奥威BI系统这类BI商业智能软件&#xff0c;那就是又快又简单。 奥威BI系统介绍&#xff1a; 奥威BI系统是一款高效的数据可视化大屏工具&…

算法-动态规划/中心扩散法-最长回文子串

算法-动态规划/中心扩散法-最长回文子串 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/longest-palindromic-substring 1.2 题目描述 2 动态规划 2.1 思路 dp[i][j] 表示[i,j]之间的字符串是否是回文。 那么&#xff0c;如果chars[i] chars[j]时&#xff0c;就…

ArmSoM-W3之RK3588安装ffmpeg

1. 简介 FFmpeg 是一个完整的、跨平台的音频和视频录制、转换和流媒体解决方案。既是一款音视频编解码工具&#xff0c;同时也是一组音视频编解码开发套件&#xff0c;作为编解码开发套件&#xff0c;它为开发者提供了丰富的音视频处理的调用接口。 FFmpeg 提供了多种媒体格式…

C++11打断线程的几种方式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pthread_cancel1.代码演示2.两个重要方法1.pthread_setcancelstate2.pthread_setcanceltype 3.资源回收 二、Boost1.看代码2.资源泄露2.资源回收 总结 前言…

腾讯云2核4G服务器一年和三年价格性能测评

腾讯云轻量2核4G5M服务器&#xff1a;CPU内存流量带宽系统盘性能测评&#xff1a;轻量应用服务器2核4G5M带宽&#xff0c;免费500GB月流量&#xff0c;60GB系统盘SSD盘&#xff0c;5M带宽下载速度可达640KB/秒&#xff0c;流量超额按照0.8元每GB的价格支付流量费&#xff0c;轻…

dubbo3+zookeeper/nacos+dubbo-admin

工程结构&#xff1a; 版本信息&#xff1a; jdk版本&#xff1a;1.8 springboot-parent版本&#xff1a;2.6.6 springboot版本&#xff1a;2.6.6 dubbo版本&#xff1a;3.0.7 curator版本&#xff1a;4.2.0 dubbo-registry-nacos版本&#xff1a;3.0.7注意事项&#xff1a;正…

Apache Ranger:(二)对Hive集成简单使用

1.Ranger Hive-plugin安装 进入 Ranger 编译生成的目录下 找到 ranger-2.0.0-hive-plugin.tar.gz 进行解压 tar -zxvf ranger-2.0.0-hive-plugin.tar.gz -C /opt/module/ 2.修改配置文件 vim install.properties #策略管理器的url地址 POLICY_MGR_URLhttp://[ip]:6080#组件…

今日头条文章采集ChatGPT3.5/4.0驱动浏览器改写文章软件说明文档

大家好了&#xff0c;我是淘小白~ 今天给大家介绍的软件是一个款驱动浏览器改写文章的软件&#xff0c;下面给大家做一下介绍说明&#xff1a; 一、软件语言 Python编写的&#xff0c;使用的库是selenium库 二、具体逻辑 1、整理头条文章网址&#xff0c;需要自己整理&…

网络基础知识面试题2

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)

VIM指令

vim的工作模式 vim一般有6种工作模式。 普通模式&#xff1a;使用vim打开一个文件时默认模式&#xff0c;也叫命令模式&#xff0c;允许用户通过各种命令浏览代码、滚屏等操作。 插入模式&#xff1a;也可以叫做编辑模式&#xff0c;在普通模式下敲击 i 、a 或 o 就进入插入模…

【广州华锐互动】VR虚拟现实技术应用于新兵作战体验的优势

随着虚拟现实(VR)技术的不断发展&#xff0c;越来越多的军校开始将其应用于军事训练中。VR技术可以通过模拟真实的环境和情境&#xff0c;为学员提供更加直观、生动的训练体验。本文将从以下几个方面阐述VR虚拟现实技术在军事作战演习中的应用场景。 1.战场模拟 通过VR技术&…

Linux shell编程学习笔记9:字符串运算 和 if语句

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、字符串、文件测试等多种运算&#xff0c;同样也需要进行根据条件进行流程控制&#xff0c;提供了if、for、while、until等语句。 上期学习笔记中我们研究了字符串数据的使用&#xff0c;今天我们研…