OpenCV4.9使用 inRange 的阈值操作

 返回:OpenCV系列文章目录(持续更新中......)

上一篇:OpenCV4.9​​​​基本阈值操作

下一篇:利用OpenCV4.9制作自己的线性滤波器!

​目标

在本教程中,您将学习如何:

  • 使用 OpenCV cv::inRange 函数执行基本阈值操作。
  • 根据 HSV 色彩空间中的像素值范围检测对象。

理论

  • 在上一教程中,我们学习了如何使用 cv::threshold 函数执行阈值。
  • 在本教程中,我们将学习如何使用 cv::inRange 函数来做到这一点。
  • 概念保持不变,但现在我们添加了一系列我们需要的像素值。

HSV 色彩空间

HSV(色调、饱和度、值)色彩空间是表示类似于 RGB 颜色模型的色彩空间的模型。由于色相通道对颜色类型进行建模,因此在需要根据颜色分割对象的图像处理任务中非常有用。饱和度的变化从不饱和到表示灰色阴影和完全饱和(无白色分量)。值通道描述颜色的亮度或强度。下图显示了 HSV 气缸。

作者:SharkD衍生作品:SharkD [CC BY-SA 3.0或GFDL],通过Wikimedia Commons

由于 RGB 色彩空间中的颜色是使用三个通道进行编码的,因此根据图像中的颜色分割图像中的对象更加困难。

作者:SharkD [GFDL或CC BY-SA 4.0],来自维基共享资源

颜色转换中介绍了使用 cv::cvtColor 函数从一个颜色空间转换为另一个颜色空间的公式

代码

C++

The tutorial code's is shown lines below. You can also download it from here

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include <iostream>
 
using namespace cv;
 
const int max_value_H = 360/2;
const int max_value = 255;
const String window_capture_name = "Video Capture";
const String window_detection_name = "Object Detection";
int low_H = 0, low_S = 0, low_V = 0;
int high_H = max_value_H, high_S = max_value, high_V = max_value;
 
static void on_low_H_thresh_trackbar(int, void *)
{
 low_H = min(high_H-1, low_H);
 setTrackbarPos("Low H", window_detection_name, low_H);
}
 
static void on_high_H_thresh_trackbar(int, void *)
{
 high_H = max(high_H, low_H+1);
 setTrackbarPos("High H", window_detection_name, high_H);
}
 
static void on_low_S_thresh_trackbar(int, void *)
{
 low_S = min(high_S-1, low_S);
 setTrackbarPos("Low S", window_detection_name, low_S);
}
 
static void on_high_S_thresh_trackbar(int, void *)
{
 high_S = max(high_S, low_S+1);
 setTrackbarPos("High S", window_detection_name, high_S);
}
 
static void on_low_V_thresh_trackbar(int, void *)
{
 low_V = min(high_V-1, low_V);
 setTrackbarPos("Low V", window_detection_name, low_V);
}
 
static void on_high_V_thresh_trackbar(int, void *)
{
 high_V = max(high_V, low_V+1);
 setTrackbarPos("High V", window_detection_name, high_V);
}
 
int main(int argc, char* argv[])
{
 VideoCapture cap(argc > 1 ? atoi(argv[1]) : 0);
 
 namedWindow(window_capture_name);
 namedWindow(window_detection_name);
 
 // Trackbars to set thresholds for HSV values
 createTrackbar("Low H", window_detection_name, &low_H, max_value_H, on_low_H_thresh_trackbar);
 createTrackbar("High H", window_detection_name, &high_H, max_value_H, on_high_H_thresh_trackbar);
 createTrackbar("Low S", window_detection_name, &low_S, max_value, on_low_S_thresh_trackbar);
 createTrackbar("High S", window_detection_name, &high_S, max_value, on_high_S_thresh_trackbar);
 createTrackbar("Low V", window_detection_name, &low_V, max_value, on_low_V_thresh_trackbar);
 createTrackbar("High V", window_detection_name, &high_V, max_value, on_high_V_thresh_trackbar);
 
 Mat frame, frame_HSV, frame_threshold;
 while (true) {
 cap >> frame;
 if(frame.empty())
 {
 break;
 }
 
 // Convert from BGR to HSV colorspace
 cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
 // Detect the object based on HSV Range Values
 inRange(frame_HSV, Scalar(low_H, low_S, low_V), Scalar(high_H, high_S, high_V), frame_threshold);
 
 // Show the frames
 imshow(window_capture_name, frame);
 imshow(window_detection_name, frame_threshold);
 
 char key = (char) waitKey(30);
 if (key == 'q' || key == 27)
 {
 break;
 }
 }
 return 0;
}

解释

C++

让我们检查一下程序的一般结构:

  • 从默认或提供的捕获设备捕获视频流。

 VideoCapture cap(argc > 1 ? atoi(argv[1]) : 0);

创建一个窗口以显示默认帧和阈值帧。

 namedWindow(window_capture_name);
 namedWindow(window_detection_name);

创建跟踪栏以设置 HSV 值的范围

 // Trackbars to set thresholds for HSV values
 createTrackbar("Low H", window_detection_name, &low_H, max_value_H, on_low_H_thresh_trackbar);
 createTrackbar("High H", window_detection_name, &high_H, max_value_H, on_high_H_thresh_trackbar);
 createTrackbar("Low S", window_detection_name, &low_S, max_value, on_low_S_thresh_trackbar);
 createTrackbar("High S", window_detection_name, &high_S, max_value, on_high_S_thresh_trackbar);
 createTrackbar("Low V", window_detection_name, &low_V, max_value, on_low_V_thresh_trackbar);
 createTrackbar("High V", window_detection_name, &high_V, max_value, on_high_V_thresh_trackbar);

在用户希望程序退出之前,请执行以下操作

 cap >> frame;
 if(frame.empty())
 {
 break;
 }
 
 // Convert from BGR to HSV colorspace
 cvtColor(frame, frame_HSV, COLOR_BGR2HSV);
 // Detect the object based on HSV Range Values
 inRange(frame_HSV, Scalar(low_H, low_S, low_V), Scalar(high_H, high_S, high_V), frame_threshold);

显示图像

 // Show the frames
 imshow(window_capture_name, frame);
 imshow(window_detection_name, frame_threshold);

对于控制较低范围的跟踪栏,例如色调值:

static void on_low_H_thresh_trackbar(int, void *)
{
 low_H = min(high_H-1, low_H);
 setTrackbarPos("Low H", window_detection_name, low_H);
}
static void on_low_H_thresh_trackbar(int, void *)
{
 low_H = min(high_H-1, low_H);
 setTrackbarPos("Low H", window_detection_name, low_H);
}

对于控制上限范围的跟踪栏,例如色调值:

static void on_high_H_thresh_trackbar(int, void *)
{
 high_H = max(high_H, low_H+1);
 setTrackbarPos("High H", window_detection_name, high_H);
}
  • 有必要找到最大值和最小值,以避免出现阈值的高值小于低值等差异。

结果

  • 编译此程序后,运行它。该程序将打开两个窗口
  • 当您从跟踪栏设置范围值时,生成的帧将在另一个窗口中可见。

参考文献:

1、《Thresholding Operations using inRange》------Lorena García

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【错题集-编程题】大数乘法(模拟 + 高精度乘法)

题目链接&#xff1a;大数乘法_牛客题霸_牛客网 (nowcoder.com) 一、分析题目 根据列竖式运算的过程模拟即可&#xff0c;但是我们可以改进⼀下列竖式的过程&#xff1a; 先计算⽆进位相乘并且相加后的结果&#xff1b;然后再处理进位。 细节&#xff1a;题目所给的两个字符串…

OpenHarmony 视频播放开发教程~

介绍 本示例主要展示了网络视频播放的相关功能。使用ohos.multimedia.avsession等接口实现视频播放的功能。 效果预览 主页 使用说明 点击播放按钮&#xff0c;应用的播放状态发生变化。点击暂停按钮&#xff0c;应用的播放状态开始变化。点击上一个按钮&#xff0c;界面展…

Ribbon 添加快速访问区域

添加快速访问区域挺简单的&#xff0c;实例如下所示&#xff1a; void QtRightFuncDemo::createQuickAccessBar() { RibbonQuickAccessBar* quickAccessBar ribbonBar()->quickAccessBar(); QAction* action quickAccessBar->actionCustomizeButton(); act…

如何查找一篇英文文献的源代码?(论文中没有源代码链接时)如何查找一篇论文的实现代码从而复现论文?

有两个网址&#xff0c;从这两个网址里面能找到论文相关代码&#xff0c;但不确定是不是人家论文里的源代码&#xff0c;但是根据论文实在找不到的情况下&#xff0c;只能试试这两个网址了 1. https://paperswithcode.com/ 2. https://www.catalyzex.com/

团队协作:如何利用 Gitee 实现多人合作项目的版本控制

文章目录 前言一、名词解释1、Git是什么&#xff1f;2、Gitee、GitHub和GitLab 二、操作步骤1.安装Git2.创建Gitee仓库3.用vscode连接仓库4. 克隆远程仓库 总结 前言 在软件开发中&#xff0c;有效地管理代码是至关重要的。Gitee 是一个功能强大的代码托管平台&#xff0c;提供…

Sentinel 流控注解使用

大概原理&#xff1a;通过反射解析注解 SentinelResource信息完成调用&#xff0c;处理方法&#xff0c;类似AOP编程 处理方法的返回类型要保持一致&#xff0c;参数和顺序保持一致&#xff0c; 可以在参数列表最后加 com.alibaba.csp.sentinel.slots.block.BlockException; …

探索C语言数据结构:利用顺序表完成通讯录的实现

在好久之前我就已经学习过顺序表&#xff0c;但是在前几天再次温习顺序表的时候&#xff0c;我惊奇的发现顺序编表可以完成我们日常使用的通讯录的功能&#xff0c;那么今天就来好好通过博客总结一下通讯录如何完成吧。 常常会回顾努力的自己&#xff0c;所以要给自己的努力留…

【JavaSE】浅谈Java异常

前言 本篇文章是对Java异常体系相关内容及部分注意事项的的讲解。 一. 认识异常 在每个人的生命历程中&#xff0c;或多或少都会遇到生病或受伤的情况&#xff0c;比如&#xff1a;皮肤擦伤、感冒、发烧、患上某些传染病等等。不管“病情”严重与否&#xff0c;这些都可以算…

数据链路层协议——以太网协议

目录 要解决的问题 以太网协议 以太网帧格式 MAC地址 MAC地址和IP地址 MTU MTU对IP协议的影响 MTU对UDP协议的影响 MTU对TCP协议的影响 ARP协议 ARP协议格式 ARP协议的工作流程 ARP缓存表 要解决的问题 上一篇我们也说了&#xff0c;数据从应用层一步步封装到了网…

leetcode:滑动窗口----3. 无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为…

工业现场ModbusTCP转EtherNETIP网关引领生物现场领新浪潮

生物质发生器是一种能够产生、培养生物的设备。客户现场需要将生物发生器连接到罗克韦尔系统&#xff0c;但是二者协议无法直接通讯&#xff0c;需要通过开疆智能ModbusTCP转Ethernet/IP网关将两者进行通讯连接&#xff0c;生物质发生器以其独特的工作原理和优势&#xff0c;使…

【命名空间详解】c++入门

目录 命名空间的定义 1.命名空间的正常定义 2.命名空间还可以嵌套 3. 命名空间可以合并 命名空间的使用 1.加命名空间名称及作用域限定符 2.使用using将命名空间中某个成员引入 3.使用using namespace 命名空间名称 引入 输入&#xff0c;输出 输出 命名空间的定义 …

[阅读笔记21][RA-CM3]Retrieval-Augmented Multimodal Language Modeling

这篇论文是meta联合斯坦福在23年4月发表的论文&#xff0c;提出了一个使用外部知识检索增强的多模态模型。 这篇模型提出的RA-CM3模型是第一个能够检索并生成图像文本的多模态模型&#xff0c;在图像文本生成任务上优于现有的多模态模型&#xff0c;同时使用更少的训练量。 RA-…

在PostgreSQL中如何处理大对象(Large Objects),例如存储和检索二进制文件?

文章目录 存储二进制文件为大对象步骤 1&#xff1a;创建一个大对象步骤 2&#xff1a;写入数据到大对象 检索大对象为二进制文件步骤 1&#xff1a;打开大对象以进行读取步骤 2&#xff1a;从大对象读取数据 注意事项 PostgreSQL 提供了对大对象&#xff08;Large Objects&…

【多线程学习】深入探究阻塞队列与生产者消费者模型和线程池常见面试题

˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如…

【vue】el-tree的新增/编辑/删除节点

1、概述 关于树形结构的新增同级节点&#xff0c;新增子级节点&#xff0c;修改节点名称&#xff0c;删除节点等四种操作&#xff0c;各种参数配置完全继承el-tree&#xff0c;本篇使用vue2 element-ui 2、效果图展示 3、调用方式 <template><Tree:data"tree…

上位机图像处理和嵌入式模块部署(树莓派4b和视觉slam十四讲)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 实际使用中&#xff0c;树莓派4b是非常好的一个基础平台。本身板子价格也不是很贵&#xff0c;建议大家多多使用。之前关于vslam&#xff0c;也就是…

CSS display属性

目录 概述&#xff1a; 设置display示例&#xff1a; none&#xff1a; block&#xff1a; inline&#xff1a; inline-block &#xff1a; 概述&#xff1a; 在CSS中我们可以使用display属性来控制元素的布局&#xff0c;我们可以通过display来设置元素的类型。 在不设置…

webpack源码分析——enhanced-resolve库之getType、normalize、join和cachedJoin函数

一、PathType 路径类型 const PathType Object.freeze({Empty: 0, // 空Normal: 1, // 默认值Relative: 2, // 相对路径AbsoluteWin: 3, // win 下的绝对路径AbsolutePosix: 4, // posix 下的绝对路径Internal: 5 // enhanced-resolve 内部自定义的一种类型&#xff0c;具体是…

Redis:报错Creating Server TCP listening socket *:6379: bind: No error

错误&#xff1a; window下启动redis服务报错&#xff1a; Creating Server TCP listening socket *:6379: bind: No error 原因&#xff1a; 端口6379已被绑定&#xff0c;应该是因为上次未关闭服务 解决&#xff1a; ①依次输入命令&#xff1a; redis-cli.exe &#xff08…