DrGraph原理示教 - OpenCV 4 功能 - 二值化

news2024/11/20 20:36:38

二值化,也就是处理结果为0或1,当然是针对图像的各像素而言的
1或0,对应于有无,也就是留下有用的,删除无用的,有用的部分,就是关心的部分
在图像处理中,也不仅仅只是1或0,因为这两个值看起来都是黑的,人眼很难分辨清楚,那就放大一些,255或0,黑白就出来了
目标识别、图像分割、目标提取等后续应用,很多会基于二值化的结果。所以图像分析的二值化处理是一个重要环节。比如CSDN的OpenCV技能树:
在这里插入图片描述

广义来说,分析或处理的结果中,各像素点只在0/255间取值,那就算是二值化,所以阈值、腐蚀与膨胀、开运算与闭运算、连通区域分析、轮廓等都算是
但在OpenCV 4中,阈值的结果可能也是彩色图像,开闭运算的输入就是二值化图像… 这个概念可能是错的,因为我还没有从头处理开闭运算。
所以,还是自己按自己的标准来处理,利于理解就行,无所谓对错

inRange

OpenCV中的inRange()函数可以实现图像的二值化,其功能是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0)。函数的语法格式如下:

void cv::inRange(InputArray _src, InputArray _lowerb, InputArray _upperb, OutputArray _dst);

其中,_src表示输入图像,可以是灰度图像或彩色图像;_lowerb表示下界的阈值,可以是一个标量值或与输入图像通道数相同的数组;_upperb表示上界的阈值,与_lowerb的类型相同,指定上界阈值;_dst表示输出图像,用于存储计算得到的阈值图像。
在这里插入图片描述
二值图像,可作为copyTo的参数,实现原图的部分拷贝
在这里插入图片描述
具体实现代码:

    cv::Mat originMat = dstMat.clone();
    int paramIndex = 0;
    bool combineMaskFlag = GetParamValue_Bool(paramIndex++);    // 0 - 过滤原图显示
    int min0 = GetParamValue_Int(paramIndex++);   // 1 - 通道0下限
    int max0 = GetParamValue_Int(paramIndex++);   // 2 - 通道0上限
    int min1 = GetParamValue_Int(paramIndex++);   // 3 - 通道1下限
    int max1 = GetParamValue_Int(paramIndex++);   // 4 - 通道1上限
    int min2 = GetParamValue_Int(paramIndex++);   // 5 - 通道2下限
    int max2 = GetParamValue_Int(paramIndex++);   // 6 - 通道2上限
    int dim = dstMat.channels();
    cv::Mat maskMat;
    if(dim == 1)
        inRange(dstMat, Scalar(min0), Scalar(max0), dstMat);
    if(dim == 2)
        inRange(dstMat, Scalar(min0, min1), Scalar(max0, max1), dstMat);
    if(dim >= 3)
        inRange(dstMat, Scalar(min0, min1, min2), Scalar(max0, max1, max2), dstMat);
    if(combineMaskFlag)
        originMat.copyTo(dstMat, dstMat);

基准偏差过滤

二值化本质上是针对各像素点进行逻辑判断处理。想明白这点,那就可以实现色通,即在指定彩色颜色相邻区域内OK,其余颜色不再关心。比如绿幕抠图,那就把绿色颜色干掉,只留下其余部分,也就是前景。好象这里说反了,不过理解起来是一样的。
基准偏差,那就是有基准,有偏差,在这个范围内是期望的,出了这个范围就不OK
在这里插入图片描述
基准可以是灰度、单通道或彩色,代码写起来很简单,我整成功能函数,以便后续调用

    cv::Mat originMat = dstMat.clone();
    int paramIndex = 0;
    bool combineMaskFlag = GetParamValue_Bool(paramIndex++);    // 0 - 过滤原图显示
    bool reverseFlag = GetParamValue_Bool(paramIndex++);        // 1 - 反相
    int channelType = GetParamValue_Int(paramIndex++);          // 2 - 基准类型
    QColor baseColor = GetParamValue_Color(paramIndex++);       // 3 - 基准值
    int delta = GetParamValue_Int(paramIndex++);                // 4 - 偏差量
    if(channelType != 5) { // 灰度基本偏差
        if(channelType == 4)    // 灰度图
            dstMat = CvHelper::ToMat_GRAY(dstMat);
        else {  // 目标单通道
            // 首先要确保有相应的通道存在
            int dstChannelNumber = channelType + 1;
            if(dstChannelNumber == 2)
                dstChannelNumber = 3;
            if(dstMat.channels() < dstChannelNumber)
                dstMat = CvHelper::ChangeMatDim(dstMat, dstChannelNumber);
            std::vector<cv::Mat> channels;
            split(dstMat, channels);
            dstMat = channels[channelType];
        }
        dstMat = CvHelper::BuildTransMaskMat(dstMat, baseColor.red() % 0x100, delta);
    } else { // 彩色基本偏差
        dstMat = CvHelper::BuildTransMaskMat(dstMat, baseColor, delta);
    }
    if(reverseFlag)
        bitwise_not(dstMat, dstMat);
    if(combineMaskFlag)
        originMat.copyTo(dstMat, dstMat);
        
// 生成MASK屏蔽图形 - 彩色基准偏差 - 色通 -> transColor ± delta之间通过,之外不过
Mat CvHelper::BuildTransMaskMat(cv::Mat &srcMat, QColor transColor, BYTE delta) {
    cv::Mat bgrMat = ToMat_BGR(srcMat);
    BYTE r = transColor.red();
    BYTE g = transColor.green();
    BYTE b = transColor.blue();
    BYTE maxR = std::min(255, int(r + delta));
    BYTE minR = std::max(0,   int(r - delta));
    BYTE maxG = std::min(255, int(g + delta));
    BYTE minG = std::max(0,   int(g - delta));
    BYTE maxB = std::min(255, int(b + delta));
    BYTE minB = std::max(0,   int(b - delta));
    cv::Mat maskMat;
    inRange(bgrMat, Scalar(minB, minG, minR), Scalar(maxB, maxG, maxR), maskMat);
    return maskMat;
}
// 生成MASK屏蔽图形 - 灰度基准偏差 - 灰通 -> transByte ± delta之间通过,之外不过
Mat CvHelper::BuildTransMaskMat(cv::Mat &srcMat, BYTE transByte, BYTE delta) {
    cv::Mat grayMat = ToMat_GRAY(srcMat);
    cv::Mat resultMat(grayMat.rows, grayMat.cols, CV_8UC1);
    BYTE * pSrc = grayMat.data;
    BYTE * pDst = resultMat.data;
    int low = transByte - delta, high = transByte + delta;
    BYTE LOW = std::max(0, low);
    BYTE HIGH = std::min(0xFF, high);
    for(int row = 0; row < grayMat.rows; ++row)
        for(int col = 0; col < grayMat.cols; ++col) {
            BYTE v = *pSrc++;
            BYTE value = 0x0;
            if(IS_IN_RANGE(v, LOW, HIGH))
                value = 0xFF;
            *pDst++ = value;
        }
    return resultMat;
}

在这里插入图片描述

分量偏差过滤

与基准偏差过滤对应的是分量偏差过滤,即各像素点分量差在目标范围内/外作为选择判断的基准。代码就太简单了。运行效果如下图所示。
在这里插入图片描述
为更实用,在逻辑处理前,先将图像转化为RGB三通道,不含A通道即可。

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

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

相关文章

Linux 命令echo

命令作用 输出一行字符串在shell中&#xff0c;可以打印变量的值输出结果写入到文件在显示器上显示一段文字&#xff0c;起到提示的作用 语法 echo [选项] [字符串] 参数 字符含义-n不自动换行-e解释转义字符-E不解释转义字符 如果-e有效&#xff0c;则识别以下序列&…

【Unity入门】RequireComponent的使用

目录 RequireComponent的作用构造函数 RequireComponent的作用 RequireComponent 属性自动将所需的组件添加为依赖项。 当某个脚本必须依赖其他脚本或者组件共同使用时&#xff0c;为了避免人为添加过程的操作失误&#xff0c;可以在代码中使用RequireComponent&#xff0c;它…

c语言:设计投票小程序|练习题

一、题目 设计一个投票小程序 如图&#xff1a; 二、代码图片【带注释】 三、源代码【带注释】 #include <stdio.h> #include<string.h> void win(int,int,int); int main() { char ch[5]; int countLili0; int countjp0; int countzx0; int …

OS 7--DNS配置+Apache发布网站

环境准备 centOS 7 1.配置DNS 1.1 域名为lianxi.com 1.2 为WWW服务器、FTP服务器、NEWS服务器做域名解析 1)安装DNS yum -y install bind bind-utils (如果安装不上&#xff0c;就把磁盘在重洗挂载一下&#xff09; 2&#xff09;修改DNS配置文件 vim /etc/resolv.conf…

【一文入门】Git常用命令集锦--分支操作和版本管理篇

前言 Git 是一种分布式版本控制系统&#xff0c;可以帮助团队协作开发、管理和维护代码&#xff0c;提高代码质量和效率&#xff0c;掌握常用版本管理命令可以帮助我们更好地管理代码变更和历史记录。下面我将介绍开发中常用的一些Git分支操作和版本管理命令 1 分支操作 1.1 …

Linux 系统编程:文件系统

文件类型 Linux 文件分为 3 类&#xff1a; 普通文件&#xff1a;文本文件、二进制文件&#xff0c;要学习如何创建、复制、移动、重命名和删除这样的文件。目录&#xff08;Windows 中的“文件夹”与之类似&#xff09;伪文件&#xff1a;设备文件、命名管道、proc 文件&…

Kafka安全认证机制详解之SASL_PLAIN

一、概述 官方文档&#xff1a; https://kafka.apache.org/documentation/#security 在官方文档中&#xff0c;kafka有五种加密认证方式&#xff0c;分别如下&#xff1a; SSL&#xff1a;用于测试环境SASL/GSSAPI (Kerberos) &#xff1a;使用kerberos认证&#xff0c;密码是…

DevSecOps研讨会: 2023年DevOps有哪些值得关注的发展与挑战

近日&#xff0c;龙智DevSecOps研讨会年终专场”趋势展望与实战探讨&#xff1a;如何打好DevOps基础、赋能创新”在上海圆满落幕。来自清晖、Jama Software、CloudBees和中新赛克的嘉宾&#xff0c;以及龙智技术与顾问咨询团队代表分别发表了主题演讲&#xff0c;分享他们在Dev…

(已解决)word如何制作和引用参考文献

文章目录 正文其他 一般使用latex&#xff0c;但是有的时候会遇到使用word的情况&#xff0c;这里记录一下word如何弄参考文献。 正文 1.首先复制你的参考文献到word里面&#xff0c;然后要编号&#xff0c;记住&#xff0c;一定要编号&#xff0c;否则到时候无法引用。 那么…

Note: Balanced Diet

Balanced Diet 平衡膳食 diet balanced Wang Peng earned his living by running a barbecue restaurant, which served delicious bacon, fried chiken breast and mutton roasted with pepper and garlic. 王鹏经营一家烧烤餐厅来谋生&#xff0c;它提供美味的培根&#xf…

C语言注意点(2)

1.使用pow函数的相关问题 局部变量n0 while(num/pow(10,n)) n; 为什么不可行 printf("%d",num/pow(10,4)%10) 为什么要提前用temp先引出来 答&#xff1a;pow函数的返回值为double类型&#xff0c;1.终止条件不会满足 2.num/pow(10,4)结果为浮点型&#xff0c;浮…

Spark一:Spark介绍、技术栈与运行模式

一、Spark简介 Spark官网 https://spark.apache.org/ 1.1 Spark是什么 Spark是一种通用的大数据计算框架&#xff0c;是基于RDD(弹性分布式数据集)的一种计算模型。 是一种由 Scala 语言开发的快速、通用、可扩展的大数据分析引擎。 1.2 Spark作用 中间结果输出 Spark的Jo…

从零开始配置kali2023环境:配置jupyter的多内核环境

在kali2023上面尝试用anaconda3&#xff0c;anaconda2安装实现配置jupyter的多内核环境时出现各种问题&#xff0c;现在可以通过镜像方式解决 1. 搜索镜像 ┌──(holyeyes㉿kali2023)-[~] └─$ sudo docker search anaconda ┌──(holyeyes㉿kali2023)-[~] └─$ sudo …

Redis数据删除策略(惰性删除+定期删除)

文章目录 Redis数据删除策略1. 惰性删除2. 定期删除3. Redis过期删除策略用的哪种&#xff1f; Redis数据删除策略 1. 惰性删除 设置key过期时间后&#xff0c;不管它&#xff0c;需要用该key时&#xff0c;再检查是否过期&#xff0c;过期就删掉她&#xff0c;没过期返回 set …

车载 Android之 核心服务 - CarPropertyService 的VehicleHAL

前言: 本文是车载Android之核心服务-CarPropertyService的第二篇&#xff0c;了解一下CarPropertyService的VehicleHAL, 第一篇在车载 Android之 核心服务 - CarPropertyService 解析-CSDN博客&#xff0c;有兴趣的 朋友可以去看下。 本节介绍 AndroidAutomotiveOS中对于 Veh…

如何在 Ubuntu 20.04 上以独立模式设置 MinIO 对象存储服务器

前些天发现了一个人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;最重要的屌图甚多&#xff0c;忍不住分享一下给大家。点击跳转到网站。 如何在 Ubuntu 20.04 上以独立模式设置 MinIO 对象存储服务器 介绍 存储非结构化对象数据 blob 并使其可通过 …

jenkins +jmeter 报告乱码解决

问题&#xff1a;生产报告会乱码的问题&#xff0c;一般是有编码格式引起的。我遇到的问题是&#xff0c;jmeter需要读取csv的数据作为参数。但是我们并不知道csv保存是什么编码格式&#xff0c;有可能不是utf-8的编码格式&#xff0c;所以会导致中文乱码的问题 解决方案&#…

sealor安装k8s

文章目录 平台介绍sealos(github下载)百度网盘 部署删除污点命令补全验证 平台介绍 模块功能描述公共部分权限管理(登录)集成K8s自身RBAC授权公共部分命名空间选择展示不通命名空间资源仪表盘命名空间|计算资源|存储资源|节点状态展示主要指标状况k8s集群node|namespace|pv创建…

【java爬虫】股票数据获取工具前后端代码

前面我们有好多文章都是在介绍股票数据获取工具&#xff0c;这是一个前后端分离项目 后端技术栈&#xff1a;springboot&#xff0c;sqlite&#xff0c;jdbcTemplate&#xff0c;okhttp 前端技术栈&#xff1a;vue&#xff0c;element-plus&#xff0c;echarts&#xff0c;ax…

Matlab论文插图绘制模板第133期—函数极坐标折线图

在之前的文章中&#xff0c;分享了Matlab函数折线图的绘制模板&#xff1a; 函数三维折线图&#xff1a; 函数网格曲面图&#xff1a; 函数曲面图&#xff1a; 函数等高线图&#xff1a; 函数等高线填充图&#xff1a; 进一步&#xff0c;再来分享一下函数极坐标折线图。 先来…