c++视觉处理-----cv::findContours函数和图像进行去噪、平滑、边缘检测和轮廓检测,动态检测图形

cv::findContours

cv::findContours 是OpenCV中用于查找图像中对象轮廓的函数。轮廓是对象的边界,通常用于对象检测、分割和形状分析。cv::findContours 函数的基本用法如下:

cv::findContours(image, contours, hierarchy, mode, method, offset = cv::Point(0, 0));
  • image: 输入的二值化图像(通常是灰度图像,经过阈值处理得到的二值图像)。
  • contours: 用于存储找到的轮廓的容器,通常是一个std::vector<std::vector<cv::Point>>
  • hierarchy: 可选参数,用于存储轮廓的层次结构信息。
  • mode: 轮廓检索模式,通常使用 cv::RETR_EXTERNAL 表示只检索最外层的轮廓。
  • method: 轮廓近似方法,通常使用 cv::CHAIN_APPROX_SIMPLE 表示只保留轮廓的端点。
  • offset: 可选参数,通常设置为 cv::Point(0, 0)

cv::findContours 将在输入图像中查找轮廓,并将找到的轮廓保存在 contours 容器中。hierarchy 参数用于存储轮廓的层次结构信息,通常在分析多个轮廓之间的关系时使用。

以下是一个示例,演示如何使用 cv::findContours 函数来查找图像中的轮廓:

#include <opencv2/opencv.hpp>int main() {cv::Mat image = cv::imread("your_binary_image.jpg", cv::IMREAD_COLOR);cv::Mat grayImage, binaryImage;if (image.empty()) {std::cerr << "无法加载图像" << std::endl;return -1;}// 将图像转换为灰度图像cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);// 阈值处理,将图像转换为二值图像cv::threshold(grayImage, binaryImage, 128, 255, cv::THRESH_BINARY);// 查找轮廓std::vector<std::vector<cv::Point>> contours;cv::findContours(binaryImage, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);// 绘制轮廓cv::Mat contourImage = cv::Mat::zeros(image.size(), CV_8UC3);cv::drawContours(contourImage, contours, -1, cv::Scalar(0, 0, 255), 2);cv::imshow("原始图像", image);cv::imshow("轮廓图像", contourImage);cv::waitKey(0);return 0;
}

在这个示例中,我们首先将彩色图像转换为灰度图像,然后进行阈值处理得到二值图像。接下来,使用 cv::findContours 查找图像中的轮廓,并将其绘制到另一个图像上。这个示例只是演示了 cv::findContours 的基本用法,您可以根据具体的应用需要进一步处理找到的轮廓。
在这里插入图片描述
要对图像进行去噪、平滑、边缘检测和轮廓检测,然后允许通过滑动条调整参数以动态检测图形

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>// 回调函数,用于处理滑动条的变化
void trackbarCallback(int threshold, void* userdata) {cv::Mat* image = static_cast<cv::Mat*>(userdata);// 去噪处理(高斯滤波)cv::Mat denoisedImage;cv::GaussianBlur(*image, denoisedImage, cv::Size(5, 5), 0);// 边缘检测(Canny)cv::Mat edges;cv::cvtColor(denoisedImage, edges, cv::COLOR_BGR2GRAY);cv::Canny(edges, edges, threshold, threshold * 2);// 查找轮廓std::vector<std::vector<cv::Point>> contours;cv::findContours(edges, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);// 绘制轮廓cv::Mat contourImage = cv::Mat::zeros(image->size(), CV_8UC3);cv::drawContours(contourImage, contours, -1, cv::Scalar(0, 0, 255), 2);cv::imshow("动态边缘检测与轮廓", contourImage);
}int main() {cv::Mat image = cv::imread("111.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "无法加载图像" << std::endl;return -1;}// 创建窗口cv::namedWindow("动态边缘检测与轮廓", cv::WINDOW_NORMAL);int initialThreshold = 100;int maxThreshold = 500;// 创建滑动条cv::createTrackbar("阈值", "动态边缘检测与轮廓", &initialThreshold, maxThreshold, trackbarCallback, &image);// 初始化trackbarCallback(initialThreshold, &image);cv::waitKey(0);return 0;
}

在这里插入图片描述

方法2

#include <opencv2/opencv.hpp>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>using namespace std;
using namespace cv;
#include <iostream>
#include <fstream>
using namespace cv; //包含cv命名空间
#include <opencv2/core/core.hpp>
#define WINDOW_NAME1 "【原始图窗口】" //为窗口标题定义的宏
#define WINDOW_NAME2 "【轮廓图】" //为窗口标题定义的宏//【全局变量声明部分】-------------------- -
// 描述: 全局变量的声明
//
Mat g_srcImage;
Mat g_grayImage;
int g_nThresh = 80;
int g_nThresh_max = 255;
RNG g_rng(12345);
Mat g_cannyMat_output;
vector<vector<Point>> g_vContours;
vector<Vec4i> g_vHierarchy;
//-------- -------------------【全局函数声明部分】-----------------------
// 描述:全局函数的声明
static void ShowHelpText();
void on_ThreshChange(int, void*);
// --【main()函数】---------------------------
// 描述: 控制台应用程序的入口函数, 我们的程序从这里开始执行
//- -------
int main(int argc, char** argv)
{//【0】改变 console字体颜色system("color 1F");//【0】显示欢迎和帮助文字ShowHelpText();// 加载源图像g_srcImage = imread("113.jpg", 1);if (!g_srcImage.data){printf("读取图片错误, 请确定目录下是否有imread函数指定的图片存在~! \n"); return false;}// 转成灰度并模糊化降噪cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);blur(g_grayImage, g_grayImage, Size(3, 3));// 创建窗口namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);imshow(WINDOW_NAME1, g_srcImage);//创建滚动条并初始化createTrackbar("canny阈值", WINDOW_NAME1, &g_nThresh, g_nThresh_max, on_ThreshChange);on_ThreshChange(0, 0);waitKey(0);return(0);
}
// -【on_ThreshChange()函数】--------------------
// 描述: 回调函数
//-
void on_ThreshChange(int, void*)
{// 用Canny算子检测边缘Canny(g_grayImage, g_cannyMat_output, g_nThresh, g_nThresh * 2, 3);// 寻找轮廓findContours(g_cannyMat_output, g_vContours, g_vHierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));// 绘出轮廓Mat drawing = Mat::zeros(g_cannyMat_output.size(), CV_8UC3);for (int i = 0; i < g_vContours.size(); i++){Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//任意值drawContours(drawing, g_vContours, i, color, 2, 8, g_vHierarchy, 0, Point());}// 显示效果图imshow(WINDOW_NAME2, drawing);
}
//---------------------------【ShowHelpText()函数】-------------------
// 描述: 输出一些帮助信息
//-
static void ShowHelpText()
{//输出欢迎信息和OpenCV版本printf("\n\n\t\t\t 当前使用的OpenCV 版本为: " CV_VERSION);
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【广州华锐互动】AR轨道交通综合教学平台的应用

轨道交通是一种复杂且精密的系统&#xff0c;涵盖了众多技术和工程学科&#xff0c;包括机械、电气和计算机科学等。对于学生来说&#xff0c;理解和掌握这些知识是一项挑战。然而&#xff0c;AR技术的出现为解决这一问题提供了可能。 通过AR技术&#xff0c;教师可以创建生动、…

国产化技术探究达梦8数据库搭建一主一从双机热备守护Data Watch集群搭建实战windows版本

国产化技术探究达梦8数据库搭建一主一从双机热备守护Data Watch集群搭建实战windows版本 如果是Linux版本达梦8部署则参考笔者另一篇博文 https://blog.csdn.net/nasen512/article/details/133737692此文章针对是windows版本的达梦部署 1、测试环境介绍 服务器类型IP地址操…

WorkPlus一站式解决方案,助力企业构建统一门户系统

在信息爆炸的时代&#xff0c;企业管理面临着海量的数据和各类业务应用的复杂性。如何实现信息的井然有序、高效管理&#xff0c;成为企业发展的关键。WorkPlus作为领先的品牌&#xff0c;致力于打造统一门户系统&#xff0c;为企业提供全方位的服务和解决方案。本文将以知乎的…

Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

Linux系统编程:编译过程以及GDB调试

编译工具链SDK&#xff08;Software Development Kit&#xff09; 在windows下编写程序&#xff0c;我们通常会用IDE&#xff0c;比如idea、vs等&#xff0c;这些工具将编译链接什么的全都暗地里解决好了我们只要写程序就行&#xff0c;但很明显&#xff0c;在Linux系统下做不…

前端axios发送请求,在请求头添加参数

1.在封装接口传参时&#xff0c;定义形参&#xff0c;params是正常传参&#xff0c;name则是我想要在请求头传参 export function getCurlList (params, name) {return request({url: ********,method: get,params,name}) } 2.接口调用 const res await getCurlList(params,…

ubuntu离线编译安装cmake 3.22.5(could not fonud OPENSSL) and cmake-versinon查不到版本问题

1、首先去cmake官网下载压缩包,例如: cmake-3.22.5.tar.gz 2、拉到ubuntu进行解压: tar -zxcf cmake-3.22.5.tar.gz 3、cd 进入目录 cd cmake-3.22.5 4、执行configure可执行文件 ./configure 如果在编译过程中出现报错:Could NOT findOpenSSL,原因可能是缺少ssl库 按…

从城市吉祥物进化到虚拟人IP需要哪些步骤?

在2023年成都全国科普日主场活动中&#xff0c;推出了全国首个科普数字形象大使“科普熊猫”&#xff0c;科普熊猫作为成都科普吉祥物&#xff0c;是如何进化为虚拟人IP&#xff0c;通过动作捕捉、AR等技术&#xff0c;活灵活现地出现在大众眼前的&#xff1f; 以广州虚拟动力虚…

【Acwing187】导弹防御系统(LIS+剪枝+贪心+dfs+迭代加深)

题目描述 看本文需要准备的知识 1.最长上升子序列&#xff08;lis&#xff09;的算法思想和算法模板 2.acwing1010拦截导弹&#xff08;lis贪心&#xff09;题解 本题题解&#xff0c;需要知道这种贪心算法 3.简单了解dfs暴力搜索、剪枝、搜索树等概念 思路讲解 dfs求最…

代数——第3章——向量空间

第三章 向量空间(Vector Spaces) fmmer mit den einfachsten Beispielen anfangen. (始终从最简单的例子开始。) ------------------------------David Hilbert 3.1 (R^n)的子空间 我们的向量空间的基础模型(本章主题)是n 维实向量空间 的子空间。我们将在本节讨论它。…

【Qt】顶层窗口和普通窗口区别以及用法

区别 在Qt项目开发中&#xff0c;经常会用到窗体控件用于显示及数据操作和其他交互等。 但&#xff0c;窗体分为顶层窗口&#xff08;Top-level Window&#xff09;和普通窗口&#xff08;Regular Window&#xff09;。 他们之间是有区别的&#xff0c;包括在项目实际中的用法…

实现动态表单的一种思路 | 京东云技术团队

一、动态表单是什么 区别于传统表单前后端配合联调的开发实现方式&#xff0c;动态表单通过一种基于元数据管理的配置化方法来实现表单的动态生成&#xff0c;并能根据配置自由增改删指定字段。实现特定需求的自助化。 图1.1 传统表单前后台协作模式 图1.2 动态表单前后台协作…

CY7C68013A芯片与FPGA

文章目录 环境软件环境其它工具 USB基础USB2.0设备组成USB设备模型USB设备分层USB Host Controller 主机控制器分类 USB HostUSB2.0 数据帧USB传输事务传输类型 芯片 cypress CY7C68013开发包安装FX3 固件程序设计步骤 驱动程序设计计算机上层应用软件USB2.0 FPGAUSB基础资料官…

单目标应用:墨西哥蝾螈优化算法(Mexican Axolotl Optimization,MAO)求解微电网优化MATLAB

一、微网系统运行优化模型 微电网优化模型介绍&#xff1a; 微电网多目标优化调度模型简介_IT猿手的博客-CSDN博客 二、墨西哥蝾螈优化算法MAO 墨西哥蝾螈优化算法&#xff08;Mexican Axolotl Optimization&#xff0c;MAO&#xff09;由Yenny Villuendas-Rey 1等人于2021…

Clion中使用C/C++开发stm32程序

前言 从刚开始学习阶段&#xff0c;一直是用的keil5开发stm32程序&#xff0c;自从看到稚晖君推荐的CLion开发嵌入式程序后&#xff0c;这次尝试在CLion上开发stm32程序。 1、配置CLion用于STM32开发的环境 这里我就不详细写了&#xff0c;没必要重新写&#xff0c;网上教程很多…

安卓-APP启动优化技术方案汇总

应用有三种启动状态&#xff1a;冷启动、温启动或热启动。每种状态都会影响应用向用户显示所需的时间。在冷启动中&#xff0c;应用从头开始启动。在另外两种状态中&#xff0c;系统需要将后台运行的应用带入前台。 我们建议您始终在假定冷启动的基础上进行优化。这样做也可以…

金融信创黄金三年:小程序生态+跨端技术框架构建

小程序应用场景生态的发展&#xff0c;受益于开源技术的发展&#xff0c;以及响应快速开发的实际业务需求&#xff0c;一些跨端框架如&#xff1a;Electron、wxPython、FinClip、Tauri、Flutter等发展也非常迅速&#xff0c;小程序生态跨端技术框架&#xff0c;不仅能满足自有超…

【C刷题】day4

一、选择题 1、设变量已正确定义&#xff0c;以下不能统计出一行中输入字符个数&#xff08;不包含回车符&#xff09;的程序段是&#xff08; &#xff09; A: n0;while(chgetchar()!\n)n; B: n0;while(getchar()!\n)n; C: for(n0;getchar()!\n…

利用SoapUI工具生成Java WebService客户端代码

一. 下载安装软件 安装SoapUI 5.4.0-EB&#xff1b;下载axis-1_4&#xff0c;下载后解压至个人目录下即可。 注&#xff1a;axis-1_4下载地址&#xff08;https://archive.apache.org/dist/ws/axis/1_4/axis-bin-1_4.zip&#xff09; 二. 创建SOAP Project 点击File–>New…

Vue-2.1scoped样式冲突

默认情况&#xff1a;写在组件中的样式会全局生效->因此很容易造成多个组件之间的样式冲突问题 1.全局样式&#xff1a;默认组件中的样式会作用到全局 2.局部样式&#xff1a;可以给组件加上scoped属性&#xff0c;可以让样式只作用于当前组件 <style scoped> <…