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

news2024/11/13 20:39:09

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.coloradmin.cn/o/1080357.html

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

相关文章

单细胞分析+实验验证,多重buff加身,学会你也能发7分+。

今天给同学们分享一篇单细胞分析实验验证的生信文章“Construction of a hypoxia-immune-related prognostic panel based on integrated single-cell and bulk RNA sequencing analyses in gastric cancer”&#xff0c;这篇文章于2023年4月26日发表在Front Immunol 期刊上&am…

JUC并发编程(一):Java内存模型(JMM)及三大特性:可见性、有序性、原子性

1.简介 在当今高流量、高并发的互联网业务场景下&#xff0c;并发编程技术显得尤为重要&#xff0c;不管是哪一门编程语言&#xff0c;掌握并发编程技术是个人进阶的必经之路。时隔一个半月没有写技术博客文章&#xff0c;有点生疏了。。。闲话少叙&#xff0c;接下来我将围绕…

在使用nohup命令后台训练pytorch模型时,关闭ssh窗口导致的训练任务失败解决方法

下班前使用终端通过SSH登陆服务器&#xff0c;用nohup命令后台训练了一个pytorch模型。第二天来公司上班发现模型训练终止&#xff0c;报如下问题。 WARNING:torch.distributed.elastic.agent.server.api:Received 1 death signal, shutting down workers WARNING:torch.distr…

2023年陕西省安全员B证证考试题库及陕西省安全员B证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年陕西省安全员B证证考试题库及陕西省安全员B证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

2023年危险化学品经营单位主要负责人证考试题库及危险化学品经营单位主要负责人试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年危险化学品经营单位主要负责人证考试题库及危险化学品经营单位主要负责人试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特…

联想携中国移动打造车路协同方案 助力重庆实现32类车联网场景

10月11日&#xff0c;联想集团在中国移动全球合作伙伴大会上首次分享了与中国移动等合作伙伴共同打造的5G车路协同案例——重庆两江协同创新区车路协同应用。联想利用基于5G智能算力技术&#xff0c;在总里程55公里路段实现了32类车联网场景。 据了解&#xff0c;重庆两江协同创…

Spark任务优化分析

一、背景 首先需要掌握 Spark DAG、stage、task的相关概念 Spark的job、stage和task的机制论述 - 知乎 task数量和rdd 分区数相关 二、任务慢的原因分析 找到运行时间比较长的stage 再进去看里面的task 可以看到某个task 读取的数据量明显比其他task 较大。 如果是sql 任…

Python爬虫提高排名

在如今竞争激烈的互联网时代&#xff0c;网站的SEO优化变得尤为重要。而Python爬虫作为一种强大的工具&#xff0c;可以帮助网站主们提升搜索排名&#xff0c;吸引更多的流量和用户。本文将为您揭秘如何利用Python爬虫来改善您的SEO优化&#xff0c;并帮助您提升搜索排名。无论…

线性代数 --- 矩阵的QR分解,A=QR

矩阵的QR分解&#xff0c;格拉姆施密特过程的矩阵表示 首先先简单的回顾一下Gram-Schmidt正交化过程的核心思想&#xff0c;如何把一组线性无关的向量构造成一组标准正交向量&#xff0c;即&#xff0c;如何把矩阵A变成矩阵Q的过程。 给定一组线性无关的向量a,b,c&#xff0c;我…

2023年【危险化学品经营单位主要负责人】模拟考试及危险化学品经营单位主要负责人作业考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人模拟考试是安全生产模拟考试一点通总题库中生成的一套危险化学品经营单位主要负责人作业考试题库&#xff0c;安全生产模拟考试一点通上危险化学品经营单位主要负责人作业手机同步练习。…

支持在线状态检查的仪表板miniboard

什么是 miniboard &#xff1f; miniboard 是带有选项卡和在线状态检查的轻量级仪表板。可以通过 GUI 或 yaml 文件进行配置。 采用 shoutrrr 通知。 什么是 Shoutrrr &#xff1f; Shoutrrr 是一个类似 caronc/apprise 的通知库&#xff0c;支持多种通知服务。 安装 在群晖上…

矿物鉴定VR实践教学平台:打造全新的沉浸式学习体验

在科技的帮助下&#xff0c;我们的学习和培训方式正在发生着深刻的变化。其中&#xff0c;虚拟现实&#xff08;VR&#xff09;技术带来的沉浸式学习体验&#xff0c;为我们提供了一种全新的学习和实践方式。本文将详细介绍一款使用VR技术的教学工具——矿物鉴定VR实践教学平台…

国外无人机蜂群作战样式进展及反蜂群策略研究

源自&#xff1a;现代防御技术 作者&#xff1a;王瑞杰, 王得朝, 丰璐, 赵正党, 陈浙梁 摘 要 科技进步和军事需求的联合推动下&#xff0c;无人机蜂群作战成为一种新兴的并能够改变战争规则的颠覆性作战样式&#xff0c;各军事强国围绕“蜂群技术和战术”展开了激烈的竞争…

[GWCTF 2019]你的名字 - SSTI注入(waf绕过)

[GWCTF 2019]你的名字 1 解题流程1.1 分析1.2 解题 2 思考总结 1 解题流程 1.1 分析 1、页面只有一个输入框&#xff0c;输入什么回显什么 2、根据特性应该是SSTI注入 1.2 解题 fuzz&#xff1a;过滤则长度1512 过滤&#xff1a;{{}}、class、mro、builtins、file、func_gl…

Android Studio展示Activty生命周期

前言 本文章以及之后文章的程序版本使用Android Studio 2022.3.1 Patch 1 版本编辑&#xff0c;使用语言为java&#xff0c;最低支持API 27 Android 8.1&#xff0c;构建工具版本如下&#xff1a; 本文章主要是介绍Activty跳转和删除&#xff0c;以备后续使用&#xff0c;所以就…

百度SEO优化的特点(方式及排名诀窍详解)

百度SEO优化的特点介绍&#xff1a; 百度SEO优化是指对网站进行优化&#xff0c;使其在百度搜索引擎中获得更好的排名&#xff0c;进而获取更多的流量和用户。百度SEO优化的特点是综合性强、效果持久、成本低廉、投资回报高。百度的搜索算法不断更新&#xff0c;所以长期稳定的…

酷开会员 | 探索火星奥秘,跟着酷开系统揭开火星神秘面纱!

酷开会员 | 探索火星奥秘&#xff0c;跟着酷开系统揭开火星神秘面纱&#xff01; 地球&#xff0c;是我们的母星。人类脚踏这颗星球坚实的大地&#xff0c;倚靠她的供给繁衍生息。然而从整个太阳系中看去&#xff0c;这个人类唯一的家园&#xff0c;也不过只是一粒悬浮在阳光中…

3.3 使用广播信道的数据链路层

思维导图&#xff1a; 3.3.1 局域网的数据链路层 ### 3.3 使用广播信道的数据链路层 #### 简介 - 广播信道支持一对多通信。 - 局域网技术在20世纪70年代末兴起&#xff0c;现在在计算机网络中占有主导地位。 #### 3.3.1 局域网的数据链路层 **局域网的特点&#xff1a;** 1…

RFID技术在锂电池生产线自动化应用

随着电动汽车和能源储存系统市场的不断扩大&#xff0c;锂离子电池作为其核心部件&#xff0c;以其高能量密度、长寿命等优点成为了主流选择。而对于锂电池智能化、高效化生产有着更高的要求&#xff0c;RFID技术的使用&#xff0c;将大幅度提高锂电池的生产产能&#xff0c;从…

高防CDN之所以强大的原因

高防CDN&#xff0c;这不仅仅是一个网络安全解决方案&#xff0c;它是您的在线堡垒&#xff0c;守护您的网站免受网络不法分子的侵袭。它究竟有何神奇之处&#xff0c;使它如此引人瞩目呢&#xff1f; 网络安全铠甲&#xff1a; 高防CDN是您的磅礴网络安全铠甲。它能够抵御多种…