当前位置: 首页 > news >正文

使用 OpenCV 进行轮廓处理和图像保存

使用 OpenCV 进行轮廓处理和图像保存

在这篇博客中,我们将展示如何使用 OpenCV 库来处理图像中的轮廓,并将处理结果保存为带有时间戳的图片。我们还将介绍如何在处理图像时应用一些条件来进行进一步的操作。

前置条件

在开始之前,请确保您已经安装了 OpenCV 库。如果尚未安装,可以通过以下命令安装:

pip install opencv-python

代码实现

包含必要的库

首先,我们需要包含必要的头文件:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <filesystem>
#include <ctime>
设置命名空间和常量

为了简化代码,我们将 std::filesystem 命名空间设置为 fs。另外,我们还定义了一个常量 limitHeight,它将用于设置某种模式:

namespace fs = std::filesystem;struct MyThread {int mode;
};const int limitHeight = 1;
主处理函数

以下是处理轮廓和保存图像的主函数。该函数接受一帧图像 frame2 和缩小后的图像 ZoomOutimage 作为输入,并将结果保存到指定文件夹中:

void processContours(const cv::Mat& frame2, const cv::Mat& ZoomOutimage, MyThread& mythread, std::string& nextColor
) {std::vector<std::vector<cv::Point>> contours;cv::findContours(frame2, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);int Ycount = 0;cv::Mat output_image = ZoomOutimage.clone();double total_white_area = 0;for (const auto& contour : contours) {cv::RotatedRect rect = cv::minAreaRect(contour);cv::Point2f box[4];rect.points(box);std::vector<cv::Point> box_points(box, box + 4);float width = rect.size.width;float height = rect.size.height;if (width == 0 || height == 0) {continue;}float aspect_ratio = std::max(width, height) / std::min(width, height);double area = cv::contourArea(contour);std::cout << "矩形大小: 宽 = " << width << ", 高 = " << height << ", 面积 = " << area << std::endl;total_white_area += area;if (0 <= aspect_ratio && aspect_ratio <= 20 && area > 0) {Ycount++;cv::polylines(output_image, box_points, true, cv::Scalar(0, 255, 0), 2);}}std::cout << "满足条件的矩形个数: " << Ycount << std::endl;std::cout << "在白色颜色范围内的总面积: " << total_white_area << std::endl;cv::Mat combined_image;cv::hconcat(std::vector<cv::Mat>{ZoomOutimage, frame2, output_image}, combined_image);std::time_t now = std::time(nullptr);char buffer[80];std::strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S", std::localtime(&now));std::string current_time(buffer);cv::putText(combined_image, current_time, cv::Point(10, combined_image.rows - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 1);std::string folder = "imageY";if (!fs::exists(folder)) {fs::create_directory(folder);}std::string filename = folder + "/output_image_" + current_time + ".jpg";cv::imwrite(filename, combined_image);if (Ycount >= 1) {mythread.mode = limitHeight;nextColor = "null";std::cout << "recognize blue" << std::endl;return;}
}
主要步骤说明
  1. 查找轮廓:使用 cv::findContours 函数在二值化图像 frame2 中查找所有轮廓。
  2. 初始化变量:定义计数器 Ycount 和结果图像 output_image,并初始化总面积 total_white_area
  3. 遍历轮廓:遍历所有轮廓,计算每个轮廓的最小外接矩形的宽、高和面积,并输出这些信息。
  4. 绘制满足条件的矩形:根据长宽比和面积条件,筛选出符合要求的矩形,并将其绘制在结果图像 output_image 上。
  5. 合并图像并添加时间戳:将原图、二值化图像和结果图像横向合并,并在合并后的图像上添加当前时间戳。
  6. 创建保存文件夹并保存图像:检查 imageY 文件夹是否存在,不存在则创建。然后使用时间戳作为文件名的一部分,将处理后的图像保存到该文件夹中。
  7. 设置模式:如果找到满足条件的矩形,则设置 mythread.modelimitHeight 并返回。

通过这篇博客,我们展示了如何使用 OpenCV 进行图像处理、轮廓分析以及结果保存。希望这些内容对您有所帮助。欢迎在评论区留言讨论!

            std::vector<std::vector<cv::Point>> contours;cv::findContours(frame2, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);// 初始化计数器和结果图像int Ycount = 0;cv::Mat output_image = ZoomOutimage.clone();double total_white_area = 0;// 遍历所有轮廓for (const auto& contour : contours) {// 获取最小外接矩形cv::RotatedRect rect = cv::minAreaRect(contour);cv::Point2f box[4];rect.points(box);std::vector<cv::Point> box_points(box, box + 4);// 计算长宽比和面积float width = rect.size.width;float height = rect.size.height;// 检查是否有零值if (width == 0 || height == 0) {continue;}float aspect_ratio = std::max(width, height) / std::min(width, height);double area = cv::contourArea(contour);// 输出矩形的大小std::cout << "矩形大小: 宽 = " << width << ", 高 = " << height << ", 面积 = " << area << std::endl;// 输出总面积total_white_area += area;// 检查长宽比和面积条件if (2 <= aspect_ratio && aspect_ratio <= 15 && area > 500) {Ycount++;cv::polylines(output_image, box_points, true, cv::Scalar(0, 255, 0), 2);}}// 显示结果std::cout << "满足条件的矩形个数: " << Ycount << std::endl;std::cout << "在白色颜色范围内的总面积: " << total_white_area << std::endl;// 将每一步处理的图像横向并列cv::Mat combined_image;cv::hconcat(std::vector<cv::Mat>{ZoomOutimage, frame2, output_image}, combined_image);// 获取当前时间std::time_t now = std::time(nullptr);char buffer[80];std::strftime(buffer, sizeof(buffer), "%Y%m%d_%H%M%S", std::localtime(&now));std::string current_time(buffer);// 在图像上绘制时间戳cv::putText(combined_image, current_time, cv::Point(10, combined_image.rows - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 1);// 使用时间戳命名文件std::string filename = "output_image_" + current_time + ".jpg";// 保存结果图像cv::imwrite(filename, combined_image);if(Ycount>=1){mythread.mode=limitHeight;nextColor="null";cout<<"recognize blue"<<endl;return;}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • flink 1.17 测试
  • VSCode上安装C#环境教程
  • springboot+vue+mybatis音乐网站的设计+PPT+论文+讲解+售后
  • kafka cmd
  • 酸性蓄电池的结构与工作原理是什么?
  • 日常进度提醒
  • 【轨物推荐】经济长波:创新周期的历史
  • Python:第三课:重要API - 集合类
  • 注册或购买的谷歌账号的辅助邮箱是否需要设置?有什么用?设置的要点是什么?
  • 使用spring-boot-starter-actuator动态修改工程日志级别
  • vue3 使用腾讯IM
  • springboot中第三方bean绑定属性
  • 基于JSP技术的弹幕视频网站管理系统
  • day 8二叉树
  • JVM结构、架构与生命周期总结
  • 【css3】浏览器内核及其兼容性
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • CAP理论的例子讲解
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • express.js的介绍及使用
  • Git的一些常用操作
  • IOS评论框不贴底(ios12新bug)
  • Objective-C 中关联引用的概念
  • oldjun 检测网站的经验
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 小程序 setData 学问多
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 智能合约开发环境搭建及Hello World合约
  • Android开发者必备:推荐一款助力开发的开源APP
  • #Linux(make工具和makefile文件以及makefile语法)
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (21)起落架/可伸缩相机支架
  • (4)STL算法之比较
  • (C++)八皇后问题
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (Ruby)Ubuntu12.04安装Rails环境
  • (solr系列:一)使用tomcat部署solr服务
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践
  • (二)Eureka服务搭建,服务注册,服务发现
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (自用)网络编程
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • *p++,*(p++),*++p,(*p)++区别?
  • ./configure,make,make install的作用(转)
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .Net Remoting常用部署结构
  • .net 调用php,php 调用.net com组件 --
  • .net 验证控件和javaScript的冲突问题
  • .Net6 Api Swagger配置
  • .NET技术成长路线架构图